For generating most, but not all figures in the manuscript.

library(tidyverse)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.0     ✓ purrr   0.3.3
✓ tibble  3.0.0     ✓ dplyr   0.8.5
✓ tidyr   1.0.2     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(cowplot)

********************************************************
Note: As of version 1.0.0, cowplot does not change the
  default ggplot2 theme anymore. To recover the previous
  behavior, execute:
  theme_set(theme_cowplot())
********************************************************
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:cowplot’:

    stamp

The following objects are masked from ‘package:dplyr’:

    intersect, setdiff, union

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(mgcv)
Loading required package: nlme

Attaching package: ‘nlme’

The following object is masked from ‘package:dplyr’:

    collapse

This is mgcv 1.8-31. For overview type 'help("mgcv-package")'.
source("UVP_2017_library.R")
Loading required package: future
Parsed with column specification:
cols(
  Cruise = col_character(),
  Station = col_character(),
  `mon/dd/yyyy` = col_character(),
  `hh:mm` = col_time(format = ""),
  `Longitude [degrees east]` = col_double(),
  `Latitude [degrees north]` = col_double(),
  `Bottom Depth [m]` = col_double(),
  `Pressure [db]` = col_double(),
  `Temperature [degrees C]` = col_double(),
  `Temperature 2 [degrees C]` = col_double(),
  `Salinity [psu]` = col_double(),
  `Salinity 2 [psu]` = col_double(),
  `Fluorescense [mg/m^3]` = col_double(),
  `Beam Transmission [%]` = col_double(),
  PAR = col_double(),
  `Oxygen [umol/kg]` = col_double(),
  `Oxygen [% saturation]` = col_double()
)
theme_set(theme_cowplot())
cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')

Particles Only

Read In Data

These read back in in UTC, since write_csv saves everthing into that time zone.

options(readr.default_locale=readr::locale(tz="Mexico/General"))
bes<- read_csv("dataOut/binned_EachSize.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
bds <- read_csv("dataOut/binned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.
ues <- read_csv("dataOut/unbinned_EachSize.csv")
Parsed with column specification:
cols(
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = ""),
  depth = col_double(),
  psd_gam = col_double(),
  vol = col_double(),
  sizeclass = col_character(),
  lb = col_double(),
  ub = col_double(),
  binsize = col_double(),
  TotalParticles = col_double(),
  nparticles = col_double(),
  n_nparticles = col_double(),
  biovolume = col_double(),
  speed = col_double(),
  flux = col_double(),
  flux_fit = col_double(),
  GamPredictTP = col_double()
)
uds <- read_csv("dataOut/unbinned_DepthSummary.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  project = col_character(),
  profile = col_character(),
  time = col_datetime(format = "")
)
See spec(...) for full column specifications.

Specify the base of the photic zone (which is inside of the OMZ) and the bae of the OMZ

PhoticBase <- 160
OMZBase <- 900
DVMBase <- 600

Figure 4

Total Particle numbers and particle size distribution slope

library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
#https://stackoverflow.com/questions/30179442/plotting-minor-breaks-on-a-log-scale-with-ggplot
log_breaks = function(maj, radix=10) {
  function(x) {
    minx         = floor(min(logb(x,radix), na.rm=T)) - 1
    maxx         = ceiling(max(logb(x,radix), na.rm=T)) + 1
    n_major      = maxx - minx + 1
    major_breaks = seq(minx, maxx, by=1)
    if (maj) {
      breaks = major_breaks
    } else {
      steps = logb(1:(radix-1),radix)
      breaks = rep(steps, times=n_major) +
               rep(major_breaks, each=radix-1)
    }
    radix^breaks
  }
}
scale_x_log_eng = function(..., radix=10) {
  scale_x_continuous(...,
                     trans=log_trans(radix),
                     breaks=log_breaks(TRUE, radix),
                     minor_breaks=log_breaks(FALSE, radix))
}

#theme_set(theme_bw)


#theme_set(theme_cowplot)

PlotParticlesmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = tot_nparticles, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) + scale_shape_manual(values = c(21:25)) +
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black"), limits = c(0, 24)) +
  scale_x_log10(breaks = c(10, 100, 1000), minor = c(5, 50, 500)) +
  #theme(legend.position = "none") +
  #scale_x_log_eng()+
  labs(y = "Depth (m)", x = "Particles / L") + 
  geom_hline(yintercept = PhoticBase, color = "darkgreen") +
  geom_hline(yintercept = OMZBase, color = "darkblue") +
  #geom_hline(yintercept = DVMBase, color = "darkgoldenrod", lty = "dashed") +
  theme(legend.position = "none")

PlotPSDmany <- uds %>% 
  filter(project == "ETNP") %>%
  ggplot(aes(x = psd, y = depth, shape = factor(day(time)), fill = hour(time))) +
 
  #geom_path(aes(x = psd_gam)) + 
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1, outline_type = "lower") +
  geom_point(alpha = .6, size = 2, stroke = 1) +
  scale_y_reverse(limits = c(1200, 0)) +
  scale_shape_manual(name = "Day", values = c(21:25)) +
  scale_fill_gradientn(name = "Hour",breaks = c(0, 6, 12, 18, 24), labels =  c("0", "6", "12", "18", "24"), colors = c("black", "blue", "white", "orange", "black"), limits = c(0, 24)) +
  labs(y = "Depth (m)", x = "Particle Size Distribution Slope") + 
  geom_hline(yintercept = PhoticBase, color = "darkgreen") +
  geom_hline(yintercept = OMZBase, color = "darkblue") +
  #geom_hline(yintercept = DVMBase, color = "darkgoldenrod", lty = "dashed") +
  coord_cartesian(clip = "off") +
  annotate(geom = "text", x = -2, y = 1100, label = "More large \n particles", inherit.aes = FALSE, size = 6) +
  annotate(geom = "text", x = -4.5, y = 1100, label = "More small \n particles", inherit.aes = FALSE, size = 6)
Ignoring unknown parameters: inherit.aesIgnoring unknown parameters: inherit.aes
  # annotation_custom(
  #     grob = textGrob(label = "More big particles", hjust = 0, gp = gpar(cex = 12)),
  #     ymin = 0,      # Vertical position of the textGrob
  #     ymax = 0,
  #     xmin = 0,         # Note: The grobs are positioned outside the plot area
  #     xmax = 0)
  

plot_grid(
  PlotParticlesmany,
  PlotPSDmany,
  rel_widths = c(1, 2),
  labels = c("A", "B")
  )
Removed 266 rows containing missing values (geom_point).Removed 266 rows containing missing values (geom_point).

ggsave("figures/ParticlesPSDMany.png")
Saving 12 x 7.41 in image
ggsave("figures/ParticlesPSDMany.svg")
Saving 12 x 7.41 in image

Figure 3 Summary Statistics

Particle number vs depth and time

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(tot_nparticles~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

FSG2 <- gam(tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

FSG3 <- gam(tot_nparticles ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

#FSG4 <- gam(tot_nparticles~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, 
    bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  8.96538    0.09655   92.86   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
            edf Ref.df     F p-value  
s(depth) 1.0000  1.000 5.663  0.0202 *
s(Day)   1.4473  1.694 2.033  0.0921 .
s(Hour)  0.6402  2.000 0.502  0.2154  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.135   Deviance explained = 17.4%
GCV = 0.68369  Scale est. = 0.64319   n = 69
summary(FSG2)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  8.96538    0.09727   92.17   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value  
s(depth) 1.000  1.000 5.741  0.0194 *
s(Day)   1.469  1.718 2.214  0.0792 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.122   Deviance explained = 15.3%
GCV = 0.68744  Scale est. = 0.65288   n = 69
summary(FSG3)

Family: gaussian 
Link function: identity 

Formula:
tot_nparticles ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   8.9654     0.1004   89.34   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
         edf Ref.df     F p-value  
s(depth)   1      1 5.736  0.0194 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.0651   Deviance explained = 7.89%
GCV = 0.71559  Scale est. = 0.69485   n = 69
#summary(FSG4)

summary(FSG1)$r.sq - summary(FSG2)$r.sq # extra R^2 explained by hour
[1] 0.01304448
summary(FSG2)$r.sq - summary(FSG3)$r.sq # extra explained by day
[1] 0.05646094
summary(FSG3)$r.sq # R^2 explained by depth
[1] 0.06511156

There is no statisticlly significant affect of time on particle number. If I take all of the time variables out and just compare to depth, there is a relationship to depth p = 0.02. But the R^2 is only 6.5%. Pretty weak

Particle size distribution vs depth and time

bdsAddTime <- bds %>%
  mutate(Hour = hour(time), Day = day(time))

FSG1 <- gam(psd~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

FSG2 <- gam(psd ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

FSG3 <- gam(psd ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

FSG4 <- gam(psd~ s(depth, k = 3)  + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

summary(FSG1)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.90483    0.01809  -215.8   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F p-value    
s(depth) 1.848  1.977 88.789  <2e-16 ***
s(Day)   1.506  1.756  0.953  0.4853    
s(Hour)  1.361  2.000  2.260  0.0424 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.716   Deviance explained = 73.6%
GCV = 0.024631  Scale est. = 0.022591  n = 69
#summary(FSG2)
#summary(FSG3)
summary(FSG4)

Family: gaussian 
Link function: identity 

Formula:
psd ~ s(depth, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -3.90483    0.01814  -215.2   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F p-value    
s(depth) 1.845  1.976 88.630  <2e-16 ***
s(Hour)  1.524  2.000  2.559  0.0409 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.714   Deviance explained = 72.8%
GCV = 0.024244  Scale est. = 0.022709  n = 69
summary(FSG3)$r.sq # R^2 of depth
[1] 0.6929817
summary(FSG4)$r.sq - summary(FSG3)$r.sq # Improvement from adding hour of the day
[1] 0.02133449
summary(FSG1)$r.sq - summary(FSG4)$r.sq # Improvement from then adding day of the week
[1] 0.001481684

PSD varies with depth, but doesn’t statistically relate to hor orday. Comparing the R2 values from models tells us that you explain 69% of varience with depth.

Figure S6

Comparing the two stations

S6A Number vs depth

PlotNParticlesEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = tot_nparticles, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  #geom_path(aes(x = tot_nparticles)) +
  #geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + scale_color_manual(values = c("gray20", "brown")) +
  labs(x = "Particles/L", y = "Depth (m)") +
  theme(legend.position = "none") +
  scale_shape_manual(values = c(1:5)) +
  geom_hline(yintercept = PhoticBase, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = OMZBase, color = "darkblue") 

PlotNParticlesEP

I removed one outlyer from p16 for visualization purposes (300 particles/l at surface)

S6B Particle size distribution vs depth

PlotPSDEP <- uds %>% 
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(x = psd, y = depth, col = project, shape = project)) +
 geom_point(alpha = 0.7, size = 2, stroke = 1) +
  geom_path(aes(x = psd_gam)) +
  geom_ribbon(aes(x = psd_gam, xmin = psd_gam - 2 * psd_seg, xmax = psd_gam + 2 * psd_seg), alpha = 0.1) +
scale_y_reverse(limits = c(1000, 0)) + scale_color_manual(values = c("gray20", "brown"))  +
  scale_shape_manual(values = c(1:5)) + labs(y = "", x = "Particle Size Distribution Slope") +
  geom_hline(yintercept = PhoticBase, color = "darkgreen") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  geom_hline(yintercept = OMZBase, color = "darkblue") 

PlotPSDEP

Figure S6 Combined

plot_grid(PlotNParticlesEP, PlotPSDEP, rel_widths = c(2,3), labels = c("A", "B"))
Removed 1211 rows containing missing values (geom_point).Removed 1211 rows containing missing values (geom_point).Removed 1211 row(s) containing missing values (geom_path).

ggsave("figures/ParticlesAndPSD_ETNPVsP16.svg")
Saving 10 x 4 in image
ggsave("figures/ParticlesAndPSD_ETNPVsP16.png")
Saving 10 x 4 in image

Figure S7

Large and spall particle number, flux and size

mainParticleComponents <- bds %>%
  filter(profile %in% c("stn_043", "p16n_100")) %>%
  select(project, profile, depth,
         tot_nparticles, small_nparticles, big_nparticles,
         tot_psd = psd, small_psd, big_psd,
         tot_flux_fit, small_flux_fit, big_flux_fit) %>%
  pivot_longer(cols = -c("project", "profile", "depth")) %>%
  separate(name, c("size", "meas")) %>%
  mutate(meas = recode(meas, nparticles = "particles/L")) %>%
  mutate(meas = factor(meas, levels = c("particles/L", "flux", "psd")))
Expected 2 pieces. Additional pieces discarded in 273 rows [7, 8, 9, 16, 17, 18, 25, 26, 27, 34, 35, 36, 43, 44, 45, 52, 53, 54, 61, 62, ...].
PlotFlx <- mainParticleComponents %>% 
  filter(meas != "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size ~ meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) + scale_x_log10() + theme(axis.title.x = element_blank(), legend.position = "none", strip.background.y = element_blank(), strip.text.y = element_blank(), plot.margin = unit(c(7,0,7,7), "pt")) + scale_color_manual(values = c(P16 = "brown", ETNP = "gray20")) + scale_shape_manual(values = c(1:5)) + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = PhoticBase, color = "darkgreen")

PlotPSD <- mainParticleComponents %>% 
  filter(meas == "psd") %>%
  ggplot(aes(y = depth, x = value, col = project, shape = project)) + facet_grid(size~meas, scales = "free_x") + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank(), axis.line.y = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), plot.margin = unit(c(7,7,26.5,0), "pt")) +
  scale_color_manual(values = c(P16 = "brown", ETNP = "gray20")) +  scale_shape_manual(values = c(1:5)) +  theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = PhoticBase, color = "darkgreen")

plot_grid(PlotFlx, PlotPSD, rel_widths = c(3, 2))
Removed 246 rows containing missing values (geom_point).Removed 123 rows containing missing values (geom_point).
ggsave("figures/BigVsSmall.svg")
Saving 7.29 x 4.5 in image
ggsave("figures/BigVsSmall.png")
Saving 7.29 x 4.5 in image

Flux small and flux tot track so closely because particle fractal dimension alpha, plus flux fractal dimension, gamma > |psd|. since the size distribution of the flux sould be PSD + ag (psd is negative in this case). Yo ucan see the variance at the one depth where psd is flatest at the very top.

Figure S4

Example particle size distributions

eg_dataline <- bds %>% 
  filter(profile == "stn_043", depth == 162.5)
eg_slope =  eg_dataline %>% pull(psd)
eg_icp = eg_dataline %>% pull(icp)
eg_vol = eg_dataline %>% pull(vol)

eg_datablock <- bes %>%
  filter(profile == "stn_043", depth == 162.5)


eg_lb = eg_datablock$lb
eg_binsize = eg_datablock$binsize
eg_nnp = exp(eg_icp + log(eg_lb) * eg_slope)

eg_np = eg_nnp * eg_binsize
eg_tp = eg_np * eg_vol
eg_df <- tibble(lb = eg_lb, n_nparticles = eg_nnp, nparticles = eg_np, TotalParticles = eg_tp)


EgNNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = n_nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Binsize & Volume Normalized \n Particles (#/L/mm)", x = "Size (mm)")

EgNP <- eg_datablock %>%
  ggplot(aes(x = lb, y = nparticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs(y = "Normalized Particles" , x = "Size (mm)")

EgTP <- eg_datablock %>%
  ggplot(aes(x = lb, y = TotalParticles)) + geom_point() + scale_x_log10() + scale_y_log10() + 
  geom_path(data = eg_df) + labs( y = "Total Particles Observed (#)", x = "Size (mm)")

plot_grid(EgNNP, EgTP, labels = c("A", "B"))
Transformation introduced infinite values in continuous y-axisTransformation introduced infinite values in continuous y-axis
ggsave("figures/ExamplePSD163m.png")
Saving 7.29 x 4.5 in image
ggsave("figures/ExamplePSD163m.svg")
Saving 7.29 x 4.5 in image

Figure 5A

Flux attenuation with respect ot depth and time. All extrapolated from the UVP and traps combined.

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
scientific_10_b <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }

scientific_10_c <- function(x) {
    xout <- gsub("1e", "10^{", format(x),fixed=TRUE)
    xout <- gsub("{-0", "{-", xout,fixed=TRUE)
    xout <- gsub("{+", "{", xout,fixed=TRUE)
    xout <- gsub("{0", "{", xout,fixed=TRUE)
    xout <- paste(xout,"}",sep="")
    return(parse(text=xout))
    
}

scale_x_log10nice <- function(name=NULL,omag=seq(-10,20),...) {
    breaks10 <- 10^omag
    scale_x_log10(breaks=breaks10,labels=scientific_10_c(breaks10),...)
}


#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlx <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10nice()+
  #scale_x_log10() + 
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black"), limits = c(0, 24)) +
  
  labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  #labs(x = "moo", y = "Depth (m)") +
  geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 20, xmax = 180, ymin = 75, ymax = 500), colour = "red", fill = NA, inherit.aes = FALSE) +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm")) +
   geom_segment(aes(y = PhoticBase, yend = PhoticBase, x = 20, xend = 500), color = "darkgreen", stroke = 0.5)+
   geom_segment(aes(y = OMZBase, yend = OMZBase, x = 20, xend = 500), color = "darkblue", stroke = 0.5) #+
Ignoring unknown parameters: strokeIgnoring unknown parameters: stroke
  #geom_segment(aes(y = DVMBase, yend = DVMBase, x = 20, xend = 500), color = "darkgoldenrod", lty = "dashed", stroke = 0.5)
  
  #+ geom_hline(yintercept = OMZBase, color = "darkblue")



pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
pltFlxLegend <- get_legend(pltFlx)
Removed 14 rows containing missing values (geom_point).
pltFlx

#plotly::ggplotly(plt1)

Figure 5B

Zooming in on where the action is happening

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxZoom <- bds %>% filter(project == "ETNP" & depth <= 500 & depth >= 75) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse()+
  #scale_x_log10() +
  scale_x_log10(breaks = c(seq(from = 20, to = 50, by = 10), seq(from = 60, to = 180, by = 20)), limits = c(20, 180)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(values = rep(21:25, 2)) + 
  scale_fill_gradientn(breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  theme(axis.text.x = element_text(angle = 90)) +
labs(x = "Smoothed Flux", y = "Depth") + theme(legend.position = "none")+
geom_hline(yintercept = 160, color = "darkgreen")

pltFlxZoom

#plotly::ggplotly(plt1)

Figure 5C

Rate of change of flux, taken to the fifth root so one can see patterns.

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3 <- bds %>% filter(project == "ETNP") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), shape = factor(day(time)), fill = hour(time), group = factor(time)))  + geom_point(size = 2, stroke = 1)+
  #geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-2.1, .6), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")+
  geom_hline(yintercept = PhoticBase, color = "darkgreen") +
  geom_hline(yintercept = OMZBase, color = "darkblue") 
  #geom_hline(yintercept = DVMBase, color = "darkgoldenrod", lty = "dashed")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3

#plotly::ggplotly(plt1pos)

Combining the plots

Within panel drawing

pgTop <- ggdraw(pltFlxNoLegend 
       ) +
  draw_plot(pltFlxZoom, .4, .25, .55, .60) +
  draw_plot_label(
    c("","B"),
    c(.05, 0.55),
    c(1, 0.85),
    size = 16
  )
Removed 14 rows containing missing values (geom_point).
pgTop

pgBottom <- plot_grid(pltDelta3, pltFlxLegend , rel_widths = c(3, 1), labels = c(“C”, ""), label_size = 14)

I don’t know whats going on below here

pgBottom <- pltDelta3  + geom_rect(aes(xmin = -2, xmax = -1.15, ymin = 170, ymax = 1000), colour = "gray50", fill = "white", inherit.aes = FALSE) + draw_plot(pltFlxLegend , -1.9, -575, .7)
pgBoth <- plot_grid(pgTop + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    pgBottom + theme(plot.margin = unit(c(0, 0, 0, 0), units = "cm")),
                    ncol = 1, rel_heights = c(4, 4), labels = c("A", "C"), label_size = 16)
Removed 33 rows containing missing values (geom_point).
pgBoth


ggsave("figures/FluxDeepDive.png")
Saving 5 x 9 in image
ggsave("figures/FluxDeepDive.svg")
Saving 5 x 9 in image

Summary stats

Test for day to day and hourly variability in rate of change of flux (fifth root transformed)

There is variability with respect to depth, and day and hour Depth p = 0.03 R^2 = 0.088. Add affect of day p = 0.004, extra R^2 = 0.11, Add affect of hour p = 0.02 extra R2 = 0.12

bdsAddTime <- bds %>% 
  mutate(Hour = hour(time) + minute(time)/60, Day = day(time) + hour(time)/24 + minute(time)/24/60)

DFG1 <- gam(pracma::nthroot(DF/DZ, 5)~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG2 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG3 <- gam(pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG_DayOnly <- gam(pracma::nthroot(DF/DZ, 5) ~  s(Day, k = 3), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

DFG_NoFifth <- gam(pracma::nthroot(DF/DZ, 1)~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= 250 & depth <=500 & project == "ETNP"))

summary(DFG1)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(depth, k = 3) + s(Day, k = 3) + 
    s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.05998  -3.065  0.00407 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F p-value  
s(depth) 1.672  1.893 3.955  0.0606 .
s(Day)   1.907  1.991 4.661  0.0190 *
s(Hour)  0.774  2.000 0.658  0.1961  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.254   Deviance explained = 33.4%
GCV = 0.1732  Scale est. = 0.15112   n = 42
summary(DFG_DayOnly)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 5) ~ s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept) -0.18385    0.06485  -2.835  0.00722 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
         edf Ref.df     F p-value  
s(Day) 1.873  1.984 3.391  0.0404 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.129   Deviance explained = 16.8%
GCV = 0.18962  Scale est. = 0.17665   n = 42
summary(DFG_NoFifth)

Family: gaussian 
Link function: identity 

Formula:
pracma::nthroot(DF/DZ, 1) ~ s(depth, k = 3) + s(Day, k = 3) + 
    s(Hour, k = 4, bs = "cc")

Parametric coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.028354   0.007924  -3.578 0.000979 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
               edf Ref.df     F p-value   
s(depth) 1.809e+00  1.963 9.247 0.00138 **
s(Day)   1.827e+00  1.970 3.361 0.06222 . 
s(Hour)  1.396e-08  2.000 0.000 0.71927   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.341   Deviance explained = 39.9%
GCV = 0.0029647  Scale est. = 0.0026375  n = 42
# summary(DFG2)
# summary(DFG3)
# 
# summary(DFG1)$r.sq - summary(DFG2)$r.sq
# summary(DFG2)$r.sq - summary(DFG3)$r.sq
# summary(DFG3)$r.sq

Time is now continuous day and hour

Plot of the gams above

#plot.new()
FluxGamPlot <- function(){
  par(mfrow = c(2,2))
  plot(DFG1)
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("C")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,1))
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,2))
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
}

FluxGamPlot()

png(filename = "./figures/FluxGamPlot.png", width = 10, height = 8, units = "in", res = 200)
FluxGamPlot()
dev.off()
png 
  2 

Figure 7

Difference from model expectations

(u mol C / m^3 / day)

disagFig <- bds %>% filter(project == "ETNP") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), shape = factor(day(time)), fill = hour(time), group = factor(time))) + geom_point(size = 2) + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) +
  #labs(x = bquote("Observed - Modeled Small Particle Flux"~(μmol/m^3/day)), y = "Depth (m)") +
  labs(x = paste("Deviation from Model", expression((μmol/m^3/day)))) +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = PhoticBase, color = "darkgreen") + geom_hline(yintercept = OMZBase, color = "darkblue") #+
  #geom_hline(yintercept = DVMBase, color = "darkgoldenrod", lty = "dashed")
disagFig

#ggsave("..figures/FluxSizeShift.svg"

 ggsave("figures/FluxSizeShift.png")
Saving 6 x 4 in image
 ggsave("figures/FluxSizeShift.svg")
Saving 6 x 4 in image

Summary statistics

# bdsAddTime <- bds %>%
#   mutate(Hour = hour(time), Day = day(time))

bdsAddTime <- bds %>%
  mutate(Hour = hour(time) + minute(time)/60, Day = day(time) + hour(time)/24 + minute(time)/24/60)

OZG1 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc"), knots = list(Hour = c(0, 24)), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

OZG2 <- gam(ospsDZ ~ s(depth, k = 3) + s(Day, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

OZG3 <- gam(ospsDZ ~ s(depth, k = 3), data = bdsAddTime %>% filter(depth >= PhoticBase & depth <=500 & project == "ETNP"))

summary(OZG1)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3) + s(Hour, k = 4, bs = "cc")

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.08042    0.01049   7.665 1.33e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.584  1.827 19.185 4.77e-06 ***
s(Day)   1.771  1.946  8.926  0.00173 ** 
s(Hour)  1.266  2.000  1.964  0.05140 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.416   Deviance explained = 45.5%
GCV = 0.0082683  Scale est. = 0.0075948  n = 69
summary(OZG2)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3) + s(Day, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.08042    0.01079   7.451 2.85e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df      F  p-value    
s(depth) 1.558  1.805 18.393 8.14e-06 ***
s(Day)   1.838  1.974  6.924  0.00415 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.382   Deviance explained = 41.3%
GCV = 0.0085853  Scale est. = 0.0080382  n = 69
summary(OZG3)

Family: gaussian 
Link function: identity 

Formula:
ospsDZ ~ s(depth, k = 3)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.08042    0.01169   6.877 2.59e-09 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Approximate significance of smooth terms:
           edf Ref.df     F  p-value    
s(depth) 1.453    1.7 17.31 2.23e-05 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

R-sq.(adj) =  0.274   Deviance explained =   29%
GCV = 0.0097831  Scale est. = 0.0094354  n = 69
summary(OZG1)$r.sq - summary(OZG2)$r.sq # Extra from Hour
[1] 0.03410746
summary(OZG2)$r.sq - summary(OZG3)$r.sq # Extrafrom Day
[1] 0.1074734
summary(OZG3)$r.sq # Depth
[1] 0.2741944

Plot of those gams Figure S10

OSMSGamPlot <- function(){
  par(mfrow = c(2,2))
  plot(OZG1)
  
  par(mfg = c(1,1))
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("A")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(1,2))
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("B")), side = 3, line = 0, adj = 0, cex = 2)
  par(mfg = c(2,1))
  abline(h = 0, col = "gray30", lwd = 2)
  mtext(expression(bold("C")), side = 3, line = 0, adj = 0, cex = 2)
}

OSMSGamPlot()

png(filename = "./figures/OSMSGamPlot.png", width = 10, height = 8, units = "in", res = 200)
OSMSGamPlot()

dev.off()
png 
  2 

Figure 3

Trap data

trapFlux3 <- read_csv("dataOut/fluxMS_distilled.csv")
Parsed with column specification:
cols(
  Class = col_character(),
  Depth = col_double(),
  TrapID = col_character(),
  TrapType = col_character(),
  SampleType = col_character(),
  C_flux = col_double(),
  C_flux_umol = col_double()
)
UVPFluxComb <- read_csv("dataOut/CombinedProfileFluxEst_DS.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  Flux = col_double()
)
UVPFluxOE <- read_csv("dataOut/ObservedVsExpectedFlux.csv")
Parsed with column specification:
cols(
  depth = col_double(),
  tn_flux = col_double(),
  profile = col_character(),
  project = col_character(),
  time = col_character(),
  tot_flux2 = col_double()
)

fluxMS_distilled_toPlot <- trapFlux3 %>%
  mutate(SampleType = recode(SampleType, `plus.p` = "plus-particles", top = "top-collector"))

Remove traps where mass spec didn’t work correctly 2-17 150 1-12 73m 1-12 148 2-14 100 |(TrapID == “2-17” & Depth == 150)

fluxMS_distilled_toPlot2 <- fluxMS_distilled_toPlot %>%
 filter(!((TrapID == "1-12") | (TrapID == "2-14" & Depth == 100)|(TrapID == "2-17" & Depth == 150)))
#fluxMS_distilled_toPlot2

Traps where mass spec didn’t work.

UVPFluxPlot00 <- UVPFluxComb %>% 
  ggplot(aes(y = depth))  + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(0, 200)) +
  geom_point(aes(y = Depth, x = C_flux_umol, shape = TrapType, ID = TrapID),
             colour = "black", stroke = 1, size = 5, data = fluxMS_distilled_toPlot2) +
  geom_line(aes(x = Flux), size = 1, color = "black") +
  geom_point(aes(x = -1, y = -1, size = "UVP Estimate")) + # dummy point for the legend
  geom_point(aes(x = tot_flux2), size = 3, shape = 21, color = "white", fill = "black", data = UVPFluxOE) +
scale_shape_manual(values = c(25, 22))+
  scale_size_manual(values = 1, name = "") +
  ylab("Depth (m)") +
  #xlab(expression(Flux µmolC/m^2/day)) +
  xlab(expression(paste("x axis ", ring(A)^2))) +
  xlab(expression(paste("Flux (µ mol C/", m^2, "/day)"))) +
  
  guides(fill = guide_legend(override.aes = list(shape = 21))) +
  theme_cowplot() + 
  theme(
        legend.position = c(0.5, 0.4),
        legend.box.background = element_rect(color = "black", size = 0.5),
        legend.margin = margin(-10, 5, 10, 5)
  ) 
Ignoring unknown aesthetics: ID
# UVPFluxPlot <- UVPFluxPlot00 +
#   geom_rect(data = data.frame(project = "ETNP"), aes(xmin = 15, xmax = 32, ymin = 45, ymax = 195), colour = "red", fill = NA, inherit.aes = FALSE)

UVPFluxPlot00

ggsave("figures/FittedFlux.png")
Saving 7.29 x 4.5 in image
ggsave("figures/FittedFlux.svg")
Saving 7.29 x 4.5 in image

Figure S2

Example particle size distribution

TPPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = TotalParticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() + geom_vline(xintercept = 1) + geom_vline(xintercept = 5) + labs(y = "Depth (m)", x = "TotalParticles Observed (#)")

nnpPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = n_nparticles, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() +
  #geom_vline(xintercept = 1) + geom_vline(xintercept = 5) +
  labs(y = "Depth (m)", x = "Binsize and Volume Normalized Particles (#/L/mm)")

FitPlot <- bes %>% filter(profile == "stn_043") %>% group_by(lb) %>% ggplot(aes(x = nnp_smooth, xmin = nnp_lower, xmax = nnp_upper, y = depth, col = log(lb), group = lb)) + scale_y_reverse(limits = c(1000, 0)) + geom_point() + scale_x_log10() + scale_color_viridis_c() + geom_path() +
  #geom_vline(xintercept = 1) + geom_vline(xintercept = 5) +
  labs(y = "Depth (m)", x = "Smoothed - Normalized Particles (#/L/mm)") + geom_errorbar(width = 10, alpha = 0.5)

npLegend <- get_legend(FitPlot + theme(legend.box.margin = margin(0, 0, 40, 200)) + labs(col = expression(log[e](Size (mm)))))
Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).
plot_grid(
  TPPlot + theme(legend.position = "none"),
  nnpPlot + theme(legend.position = "none"),
  npLegend ,
  FitPlot + theme(legend.position = "none"), 
  labels = c("A", "B", "", "C")
)
Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Transformation introduced infinite values in continuous x-axisTransformation introduced infinite values in continuous x-axisRemoved 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).Removed 325 rows containing missing values (geom_point).Removed 325 row(s) containing missing values (geom_path).

ggsave("figures/AllParticleSizes.svg")
Saving 10 x 6.18 in image
ggsave("figures/AllParticleSizes.png")
Saving 10 x 6.18 in image

Figure 6

Weber Bianchi Figs

Just station 043

We are smoothing the station 043 data, with respect to depth and time. We are using this station because it is the only one to extend past 2000m. We find that the other profiles seem to give strange values near the ends of the ranges of the gams.

SameGam <- gam(TotalParticles ~s(log(lb), log(depth)), offset = log(vol * binsize), family = nb(),
    data = bes %>% filter(project == "ETNP", depth <= 2000, profile == "stn_043")) # Looks good!
gam.check(SameGam)


Method: REML   Optimizer: outer newton
full convergence after 4 iterations.
Gradient range [1.180573e-06,5.441536e-06]
(score 2243.109 & scale 1).
Hessian positive definite, eigenvalue range [5.359006,135.6228].
Model rank =  30 / 30 

Basis dimension (k) checking results. Low p-value (k-index<1) may
indicate that k is too low, especially if edf is close to k'.

                      k' edf k-index p-value    
s(log(lb),log(depth)) 29  21    0.61  <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

besE <- bes %>% filter(project == "ETNP")

lb_new <- exp(seq(from = log(0.1), to = log(2.1), by = 0.05))
ub_new <- lead(lb_new)
binsize_new <- ub_new - lb_new

lbbs <- tibble(lb = lb_new, ub = ub_new, binsize = binsize_new)

Expanded <- expand_grid(lb = exp(seq(from = log(0.1), to = log(2), by = 0.05)), depth = seq(from = 20, to = 2000, by = 20), time = as.factor(unique(besE$time))) %>% left_join(lbbs, by = "lb")

Pred <- exp(predict(SameGam, Expanded))
ToPlot <- bind_cols(Expanded, nnparticles = Pred) %>% mutate(time = as.character(time)) %>% mutate(nparticles = nnparticles * binsize)
WBColorMap <- ToPlot %>% filter(lb <= 2) %>%
  ggplot(aes(x = lb, y = depth, fill = log10(nnparticles), z = log10(nnparticles))) + geom_tile() + scale_fill_viridis_c(name = expression(log[10](Particles/m^3/mm))) + scale_y_reverse() + scale_x_log10() + geom_contour(color = "black") + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept = OMZBase, color = "darkblue") + labs(y = "Depth (m)", x = "Size (mm)")
WBColorMap

mbGam <- ToPlot %>% group_by(depth)  %>% nest() %>%
  mutate(mod = map(data, ~gam(log(nnparticles) ~ log(lb), family = gaussian(), data = .))) %>% 
  mutate(psd = map_dbl(mod, ~summary(.)$p.coeff[2])) 

Particle size distribution, smoothed over all stations

pWBPSD <- mbGam %>%
  ggplot(aes(x = psd, y = depth)) + geom_path() + scale_y_reverse()  + geom_hline(yintercept = 160, color = "darkgreen") + geom_hline(yintercept =  OMZBase, color = "darkblue") + labs(y = "Depth (m)", x = "Particle Size Distribution Slope")
pWBPSD

Large Particle Biomass

PubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb < 0.5) %>% group_by(depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup()
photicBiomass <- PubDf %>% filter(depth <= 165, depth >= 155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
PubDf <- PubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBS <- PubDf %>% 
  ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1.2)) + geom_hline(yintercept = 160, color = "darkgreen") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = OMZBase, color = "darkblue") + labs( x = "Small particle mass (norm.)")  + theme(axis.title.y = element_blank())
pWBS

#Small Particle Biomass

LubDf <- ToPlot %>% mutate(ubiomass = nparticles * lb ^ ag_global) %>% filter(lb >= 0.5) %>% group_by(time, depth) %>% summarize(ubiomass = sum(ubiomass)) %>% ungroup %>% group_by(depth)  %>% summarise(ubiomass = mean(ubiomass))
photicBiomass <- LubDf %>% filter(depth <= 165, depth >=155) %>% summarize(ubiomass = mean(ubiomass)) %>% pull(ubiomass)
LubDf <- LubDf %>% mutate(nbiomass = ubiomass/photicBiomass)
pWBL <- LubDf %>% ggplot(aes(x = nbiomass, y = depth)) + geom_path() + scale_y_reverse() + scale_x_continuous(limits = c(0,1)) + geom_hline(yintercept = 160, color = "darkgreen") + labs( x = "Large particle mass (norm.)") + geom_vline(xintercept = 1, color = "gray50") + geom_vline(xintercept = 0, color = "gray50") + geom_hline(yintercept = OMZBase, color = "darkblue") + theme(axis.title.y = element_blank())
pWBL

Combine the three lower pannels

WBFig5 <- plot_grid(pWBPSD, pWBS,pWBL, nrow = 1, labels = c("B", "C", "D"))
Removed 6 row(s) containing missing values (geom_path).Removed 7 row(s) containing missing values (geom_path).
WBFig5

Four panel figure of Weber and Bianchi equivalent data

WBcombined <- plot_grid(WBColorMap + theme(plot.margin = unit(c(0,3,0, 3), "cm")), WBFig5, ncol = 1, labels = c("A", ""))
WBcombined


ggsave("figures/WBModelValidation.png")
Saving 8.5 x 6 in image

Figure S8

P16 Flux

Flux

scientific_10 <- function(x) {parse(text=gsub("e\\+*", " %*% 10^", scales::scientific_format()(x))) }
#https://stackoverflow.com/questions/10762287/how-can-i-format-axis-labels-with-exponents-with-ggplot2-and-scales
#jacob_magnitude <- function(x){expression(10^round(log10(x)))}

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltFlxP16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = Flux_Smooth, group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_log10(limits = c(35, 150),breaks = seq(from = 20, to = 150, by = 20)) +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  
labs(x = bquote(Smoothed~Flux~(µmol~C/m^2/d)), y = "Depth (m)") +
  geom_hline(yintercept = 200, color = "darkgreen") +
  theme(axis.text.x = element_text(angle = 90, vjust = .3), legend.spacing = unit(.1, "cm"))
# 
# 
# 
# pltFlxNoLegend <- pltFlx + theme(legend.position = "none")
# pltFlxLegend <- get_legend(pltFlx)
# 
pltFlxP16

# #plotly::ggplotly(plt1)

Rate of change of flux – fifth root transformed

cb10 <- c('#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a')
pltDelta3P16 <- bds %>% filter(project == "P16") %>% #filter(DFP > 1) %>% #filter(profile %in% c("stn_043", "p16n_100")) %>%
  ggplot(aes(y = depth, x = pracma::nthroot(DF/DZ, 5), group = factor(time)))  + geom_point(size = 3, stroke = 1)+
  geom_path() +
  scale_y_reverse(limits = c(1000, 0))+
  scale_x_continuous(limits = c(-1, .1), breaks = seq(from = -2, to = .75, by = 0.5)) +
  #scale_x_log10() +
   scale_color_gradient2(low = "darkgreen", mid = "gray80", high = "purple", midpoint = 10) + scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + 
  scale_fill_gradientn(name = "Hour", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) +
  geom_vline(xintercept = 0) +
  geom_hline(yintercept = 200, color = "darkgreen")+
  labs(x = bquote((DF/DZ)^{1/5}~(µmolC/m^3/d)^{1/5}), y = "Depth (m)") + theme(legend.pos = "none")
  #labs(x = "(DF/DZ) ^ 1/5 (µmol C/m^3/d) ^ 1/5")

pltDelta3P16

#plotly::ggplotly(plt1pos)

Difference from model

osms_p16 <- bds %>% filter(project == "P16") %>%
  ggplot(aes(y = depth, x = pracma::nthroot(ospsDZ, 3), group = factor(time))) + geom_point(size = 3) + geom_path() + scale_y_reverse(limits = c(1000, 0)) +
  scale_x_continuous(limits = c(-1, 1)) +
  geom_vline(xintercept = 0) +   scale_shape_manual(name = "Day of Month", values = rep(21:25, 2)) + labs(x = "Observed - Modeled Small Particle Flux \n µmol/m^3/day") +
  scale_fill_gradientn(name = "Hour of Day", breaks = c(0, 6, 12, 18, 24), colors = c("black", "blue", "white", "orange", "black")) + geom_hline(yintercept = PhoticBase, color = "darkgreen") 
plotly::ggplotly(osms_p16)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

#ggsave("..figures/FluxSizeShift.svg"

Combine everything together

plot_grid(
  pltFlxP16,
  pltDelta3P16,
  osms_p16
)
Removed 28 rows containing missing values (geom_point).Removed 28 row(s) containing missing values (geom_path).Removed 32 rows containing missing values (geom_point).Removed 32 row(s) containing missing values (geom_path).Removed 29 rows containing missing values (geom_point).Removed 29 row(s) containing missing values (geom_path).

ggsave("figures/P16FluxRelate.svg")
Saving 8 x 8 in image
ggsave("figures/P16FluxRelate.png")
Saving 8 x 8 in image

Figure S10

Flux attenuation example

Take one profile, attenuate it, and show what it looks like

source("ModelStuff.R")
Parsed with column specification:
cols(
  Cruise = col_character(),
  Station = col_character(),
  `mon/dd/yyyy` = col_character(),
  `hh:mm` = col_time(format = ""),
  `Longitude [degrees east]` = col_double(),
  `Latitude [degrees north]` = col_double(),
  `Bottom Depth [m]` = col_double(),
  `Pressure [db]` = col_double(),
  `Temperature [degrees C]` = col_double(),
  `Temperature 2 [degrees C]` = col_double(),
  `Salinity [psu]` = col_double(),
  `Salinity 2 [psu]` = col_double(),
  `Fluorescense [mg/m^3]` = col_double(),
  `Beam Transmission [%]` = col_double(),
  PAR = col_double(),
  `Oxygen [umol/kg]` = col_double(),
  `Oxygen [% saturation]` = col_double()
)
scan_for_example <- bds %>% filter(project == "ETNP", depth < 500, depth > 200) %>% select(profile, depth, DFP, use_this_DFP, ospsDZ)

#loc_station = "stn_036"
loc_station = "stn_043"
loc_depth = 225
loc_prev_depth = 112.5

allDFPs <- bds %>% filter(profile == loc_station, depth >= loc_prev_depth, depth <= loc_depth) %>% summarize(DFP = prod(DFP), use_this_DFP = prod(use_this_DFP))

loc_DFP <-  allDFPs %>% pull(DFP)
loc_use_DFP <- allDFPs %>% pull(use_this_DFP)


for_single_disag <- bes %>% filter(profile == loc_station, depth %in% c(loc_prev_depth, loc_depth)) %>% select(depth, lb, nnp_smooth) %>%
  mutate(depth = recode(depth, `112.5` = "Shallow", `225` = "Deep")) %>% # I have no idea how to not hard code this bit
  pivot_wider(names_from = depth, values_from = nnp_smooth) 

with_disag <- for_single_disag %>%
  mutate(Predicted_Deep = remin_smooth_shuffle(Shallow, loc_use_DFP)) 
#remin_smooth_shuffle(for_single_disag$Shallow,loc_use_DFP)

for_plot_disag <- with_disag %>% pivot_longer(cols = -lb) %>% #filter(lb <= 5) %>%
  mutate(name = factor(name, levels = c("Shallow", "Deep", "Predicted_Deep"))) %>%
  mutate(name = recode_factor(name, Shallow = "Shallow (112.5m)", Deep = "Deep (225m)", Predicted_Deep = "Predicted Deep (225m)"))

for_plot_disag %>% ggplot(aes(x = lb, y = value, shape = name)) + geom_point() + scale_x_log10() + scale_y_log10() + scale_shape_manual(values = c(1, 6, 3)) + theme(legend.title = element_blank()) + labs(x = "Particle Size (mm)", y = "Normalized Particle Abundance (#/L/mm)")

ggsave("figures/DisagExample.png")
Saving 7.29 x 4.5 in image
ggsave("figures/DisagExample.svg")
Saving 7.29 x 4.5 in image

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKLS0tCgpGb3IgZ2VuZXJhdGluZyBtb3N0LCBidXQgbm90IGFsbCBmaWd1cmVzIGluIHRoZSBtYW51c2NyaXB0LgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KG1nY3YpCnNvdXJjZSgiVVZQXzIwMTdfbGlicmFyeS5SIikKdGhlbWVfc2V0KHRoZW1lX2Nvd3Bsb3QoKSkKY2IxMCA8LSBjKCcjYTZjZWUzJywnIzFmNzhiNCcsJyNiMmRmOGEnLCcjMzNhMDJjJywnI2ZiOWE5OScsJyNlMzFhMWMnLCcjZmRiZjZmJywnI2ZmN2YwMCcsJyNjYWIyZDYnLCcjNmEzZDlhJykKYGBgCgoKIyBQYXJ0aWNsZXMgT25seQoKIyBSZWFkIEluIERhdGEKVGhlc2UgcmVhZCBiYWNrIGluIGluIFVUQywgc2luY2Ugd3JpdGVfY3N2IHNhdmVzIGV2ZXJ0aGluZyBpbnRvIHRoYXQgdGltZSB6b25lLgoKYGBge3J9Cm9wdGlvbnMocmVhZHIuZGVmYXVsdF9sb2NhbGU9cmVhZHI6OmxvY2FsZSh0ej0iTWV4aWNvL0dlbmVyYWwiKSkKYmVzPC0gcmVhZF9jc3YoImRhdGFPdXQvYmlubmVkX0VhY2hTaXplLmNzdiIpCmJkcyA8LSByZWFkX2NzdigiZGF0YU91dC9iaW5uZWRfRGVwdGhTdW1tYXJ5LmNzdiIpCnVlcyA8LSByZWFkX2NzdigiZGF0YU91dC91bmJpbm5lZF9FYWNoU2l6ZS5jc3YiKQp1ZHMgPC0gcmVhZF9jc3YoImRhdGFPdXQvdW5iaW5uZWRfRGVwdGhTdW1tYXJ5LmNzdiIpCmBgYAoKU3BlY2lmeSB0aGUgYmFzZSBvZiB0aGUgcGhvdGljIHpvbmUgKHdoaWNoIGlzIGluc2lkZSBvZiB0aGUgT01aKSBhbmQgdGhlIGJhZSBvZiB0aGUgT01aCmBgYHtyfQpQaG90aWNCYXNlIDwtIDE2MApPTVpCYXNlIDwtIDkwMApEVk1CYXNlIDwtIDYwMApgYGAKCgojIEZpZ3VyZSA0CiMjIFRvdGFsIFBhcnRpY2xlIG51bWJlcnMgYW5kIHBhcnRpY2xlIHNpemUgZGlzdHJpYnV0aW9uIHNsb3BlCgpgYGB7ciBmaWcud2lkdGggPSAxMn0KbGlicmFyeShzY2FsZXMpCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMDE3OTQ0Mi9wbG90dGluZy1taW5vci1icmVha3Mtb24tYS1sb2ctc2NhbGUtd2l0aC1nZ3Bsb3QKbG9nX2JyZWFrcyA9IGZ1bmN0aW9uKG1haiwgcmFkaXg9MTApIHsKICBmdW5jdGlvbih4KSB7CiAgICBtaW54ICAgICAgICAgPSBmbG9vcihtaW4obG9nYih4LHJhZGl4KSwgbmEucm09VCkpIC0gMQogICAgbWF4eCAgICAgICAgID0gY2VpbGluZyhtYXgobG9nYih4LHJhZGl4KSwgbmEucm09VCkpICsgMQogICAgbl9tYWpvciAgICAgID0gbWF4eCAtIG1pbnggKyAxCiAgICBtYWpvcl9icmVha3MgPSBzZXEobWlueCwgbWF4eCwgYnk9MSkKICAgIGlmIChtYWopIHsKICAgICAgYnJlYWtzID0gbWFqb3JfYnJlYWtzCiAgICB9IGVsc2UgewogICAgICBzdGVwcyA9IGxvZ2IoMToocmFkaXgtMSkscmFkaXgpCiAgICAgIGJyZWFrcyA9IHJlcChzdGVwcywgdGltZXM9bl9tYWpvcikgKwogICAgICAgICAgICAgICByZXAobWFqb3JfYnJlYWtzLCBlYWNoPXJhZGl4LTEpCiAgICB9CiAgICByYWRpeF5icmVha3MKICB9Cn0Kc2NhbGVfeF9sb2dfZW5nID0gZnVuY3Rpb24oLi4uLCByYWRpeD0xMCkgewogIHNjYWxlX3hfY29udGludW91cyguLi4sCiAgICAgICAgICAgICAgICAgICAgIHRyYW5zPWxvZ190cmFucyhyYWRpeCksCiAgICAgICAgICAgICAgICAgICAgIGJyZWFrcz1sb2dfYnJlYWtzKFRSVUUsIHJhZGl4KSwKICAgICAgICAgICAgICAgICAgICAgbWlub3JfYnJlYWtzPWxvZ19icmVha3MoRkFMU0UsIHJhZGl4KSkKfQoKI3RoZW1lX3NldCh0aGVtZV9idykKCgojdGhlbWVfc2V0KHRoZW1lX2Nvd3Bsb3QpCgpQbG90UGFydGljbGVzbWFueSA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdG90X25wYXJ0aWNsZXMsIHkgPSBkZXB0aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSkpKSArCiAKICAjZ2VvbV9wYXRoKGFlcyh4ID0gcHNkX2dhbSkpICsgCiAgI2dlb21fcmliYm9uKGFlcyh4ID0gcHNkX2dhbSwgeG1pbiA9IHBzZF9nYW0gLSAyICogcHNkX3NlZywgeG1heCA9IHBzZF9nYW0gKyAyICogcHNkX3NlZyksIGFscGhhID0gMC4xLCBvdXRsaW5lX3R5cGUgPSAibG93ZXIiKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IC42LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsIDApKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIiksIGxpbWl0cyA9IGMoMCwgMjQpKSArCiAgc2NhbGVfeF9sb2cxMChicmVha3MgPSBjKDEwLCAxMDAsIDEwMDApLCBtaW5vciA9IGMoNSwgNTAsIDUwMCkpICsKICAjdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgI3NjYWxlX3hfbG9nX2VuZygpKwogIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlBhcnRpY2xlcyAvIEwiKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IFBob3RpY0Jhc2UsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBPTVpCYXNlLCBjb2xvciA9ICJkYXJrYmx1ZSIpICsKICAjZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gRFZNQmFzZSwgY29sb3IgPSAiZGFya2dvbGRlbnJvZCIsIGx0eSA9ICJkYXNoZWQiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKUGxvdFBTRG1hbnkgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JQogIGdncGxvdChhZXMoeCA9IHBzZCwgeSA9IGRlcHRoLCBzaGFwZSA9IGZhY3RvcihkYXkodGltZSkpLCBmaWxsID0gaG91cih0aW1lKSkpICsKIAogICNnZW9tX3BhdGgoYWVzKHggPSBwc2RfZ2FtKSkgKyAKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEsIG91dGxpbmVfdHlwZSA9ICJsb3dlciIpICsKICBnZW9tX3BvaW50KGFscGhhID0gLjYsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwgMCkpICsKICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkiLCB2YWx1ZXMgPSBjKDIxOjI1KSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsYnJlYWtzID0gYygwLCA2LCAxMiwgMTgsIDI0KSwgbGFiZWxzID0gIGMoIjAiLCAiNiIsICIxMiIsICIxOCIsICIyNCIpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpLCBsaW1pdHMgPSBjKDAsIDI0KSkgKwogIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBQaG90aWNCYXNlLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gT01aQmFzZSwgY29sb3IgPSAiZGFya2JsdWUiKSArCiAgI2dlb21faGxpbmUoeWludGVyY2VwdCA9IERWTUJhc2UsIGNvbG9yID0gImRhcmtnb2xkZW5yb2QiLCBsdHkgPSAiZGFzaGVkIikgKwogIGNvb3JkX2NhcnRlc2lhbihjbGlwID0gIm9mZiIpICsKICBhbm5vdGF0ZShnZW9tID0gInRleHQiLCB4ID0gLTIsIHkgPSAxMTAwLCBsYWJlbCA9ICJNb3JlIGxhcmdlIFxuIHBhcnRpY2xlcyIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHNpemUgPSA2KSArCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeCA9IC00LjUsIHkgPSAxMTAwLCBsYWJlbCA9ICJNb3JlIHNtYWxsIFxuIHBhcnRpY2xlcyIsIGluaGVyaXQuYWVzID0gRkFMU0UsIHNpemUgPSA2KQogICMgYW5ub3RhdGlvbl9jdXN0b20oCiAgIyAgICAgZ3JvYiA9IHRleHRHcm9iKGxhYmVsID0gIk1vcmUgYmlnIHBhcnRpY2xlcyIsIGhqdXN0ID0gMCwgZ3AgPSBncGFyKGNleCA9IDEyKSksCiAgIyAgICAgeW1pbiA9IDAsICAgICAgIyBWZXJ0aWNhbCBwb3NpdGlvbiBvZiB0aGUgdGV4dEdyb2IKICAjICAgICB5bWF4ID0gMCwKICAjICAgICB4bWluID0gMCwgICAgICAgICAjIE5vdGU6IFRoZSBncm9icyBhcmUgcG9zaXRpb25lZCBvdXRzaWRlIHRoZSBwbG90IGFyZWEKICAjICAgICB4bWF4ID0gMCkKICAKCnBsb3RfZ3JpZCgKICBQbG90UGFydGljbGVzbWFueSwKICBQbG90UFNEbWFueSwKICByZWxfd2lkdGhzID0gYygxLCAyKSwKICBsYWJlbHMgPSBjKCJBIiwgIkIiKQogICkKCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNQU0RNYW55LnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNQU0RNYW55LnN2ZyIpCgpgYGAKCiMjIEZpZ3VyZSAzIFN1bW1hcnkgU3RhdGlzdGljcwoKIyMjIFBhcnRpY2xlIG51bWJlciB2cyBkZXB0aCBhbmQgdGltZQoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JQogIG11dGF0ZShIb3VyID0gaG91cih0aW1lKSwgRGF5ID0gZGF5KHRpbWUpKQoKRlNHMSA8LSBnYW0odG90X25wYXJ0aWNsZXN+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSBQaG90aWNCYXNlICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0cyIDwtIGdhbSh0b3RfbnBhcnRpY2xlcyB+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gUGhvdGljQmFzZSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKRlNHMyA8LSBnYW0odG90X25wYXJ0aWNsZXMgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gUGhvdGljQmFzZSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKI0ZTRzQgPC0gZ2FtKHRvdF9ucGFydGljbGVzfiBzKGRlcHRoLCBrID0gMykgICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gUGhvdGljQmFzZSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKc3VtbWFyeShGU0cxKQpzdW1tYXJ5KEZTRzIpCnN1bW1hcnkoRlNHMykKI3N1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMSkkci5zcSAtIHN1bW1hcnkoRlNHMikkci5zcSAjIGV4dHJhIFJeMiBleHBsYWluZWQgYnkgaG91cgpzdW1tYXJ5KEZTRzIpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EgIyBleHRyYSBleHBsYWluZWQgYnkgZGF5CnN1bW1hcnkoRlNHMykkci5zcSAjIFJeMiBleHBsYWluZWQgYnkgZGVwdGgKYGBgClRoZXJlIGlzIG5vIHN0YXRpc3RpY2xseSBzaWduaWZpY2FudCBhZmZlY3Qgb2YgdGltZSBvbiBwYXJ0aWNsZSBudW1iZXIuCklmIEkgdGFrZSBhbGwgb2YgdGhlIHRpbWUgdmFyaWFibGVzIG91dCBhbmQganVzdCBjb21wYXJlIHRvIGRlcHRoLCB0aGVyZSBpcyBhIHJlbGF0aW9uc2hpcCB0byBkZXB0aCBwID0gMC4wMi4gQnV0IHRoZSBSXjIgaXMgb25seSA2LjUlLiBQcmV0dHkgd2VhawoKCiMjIyBQYXJ0aWNsZSBzaXplIGRpc3RyaWJ1dGlvbiB2cyBkZXB0aCBhbmQgdGltZQoKCgpgYGB7cn0KYmRzQWRkVGltZSA8LSBiZHMgJT4lCiAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpGU0cxIDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSBQaG90aWNCYXNlICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0cyIDwtIGdhbShwc2QgfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IFBob3RpY0Jhc2UgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkZTRzMgPC0gZ2FtKHBzZCB+IHMoZGVwdGgsIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSBQaG90aWNCYXNlICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpGU0c0IDwtIGdhbShwc2R+IHMoZGVwdGgsIGsgPSAzKSAgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSBQaG90aWNCYXNlICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpzdW1tYXJ5KEZTRzEpCiNzdW1tYXJ5KEZTRzIpCiNzdW1tYXJ5KEZTRzMpCnN1bW1hcnkoRlNHNCkKCnN1bW1hcnkoRlNHMykkci5zcSAjIFJeMiBvZiBkZXB0aApzdW1tYXJ5KEZTRzQpJHIuc3EgLSBzdW1tYXJ5KEZTRzMpJHIuc3EgIyBJbXByb3ZlbWVudCBmcm9tIGFkZGluZyBob3VyIG9mIHRoZSBkYXkKc3VtbWFyeShGU0cxKSRyLnNxIC0gc3VtbWFyeShGU0c0KSRyLnNxICMgSW1wcm92ZW1lbnQgZnJvbSB0aGVuIGFkZGluZyBkYXkgb2YgdGhlIHdlZWsKCmBgYApQU0QgdmFyaWVzIHdpdGggZGVwdGgsIGJ1dCBkb2Vzbid0IHN0YXRpc3RpY2FsbHkgcmVsYXRlIHRvIGhvciBvcmRheS4KQ29tcGFyaW5nIHRoZSBSMiB2YWx1ZXMgZnJvbSBtb2RlbHMgdGVsbHMgdXMgdGhhdCB5b3UgZXhwbGFpbiA2OSUgb2YgdmFyaWVuY2Ugd2l0aCBkZXB0aC4KCiMgRmlndXJlIFM2CiMjIENvbXBhcmluZyB0aGUgdHdvIHN0YXRpb25zCgojIyMgUzZBIE51bWJlciB2cyBkZXB0aApgYGB7cn0KUGxvdE5QYXJ0aWNsZXNFUCA8LSB1ZHMgJT4lIAogIGZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB0b3RfbnBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArCiBnZW9tX3BvaW50KGFscGhhID0gMC43LCBzaXplID0gMiwgc3Ryb2tlID0gMSkgKwogICNnZW9tX3BhdGgoYWVzKHggPSB0b3RfbnBhcnRpY2xlcykpICsKICAjZ2VvbV9yaWJib24oYWVzKHggPSBwc2RfZ2FtLCB4bWluID0gcHNkX2dhbSAtIDIgKiBwc2Rfc2VnLCB4bWF4ID0gcHNkX2dhbSArIDIgKiBwc2Rfc2VnKSwgYWxwaGEgPSAwLjEpICsKc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyYXkyMCIsICJicm93biIpKSArCiAgbGFicyh4ID0gIlBhcnRpY2xlcy9MIiwgeSA9ICJEZXB0aCAobSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTo1KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IFBob3RpY0Jhc2UsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyMDAsIGNvbG9yID0gImRhcmtncmVlbiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBPTVpCYXNlLCBjb2xvciA9ICJkYXJrYmx1ZSIpIAoKUGxvdE5QYXJ0aWNsZXNFUApgYGAKCkkgcmVtb3ZlZCBvbmUgb3V0bHllciBmcm9tIHAxNiBmb3IgdmlzdWFsaXphdGlvbiBwdXJwb3NlcyAoMzAwIHBhcnRpY2xlcy9sIGF0IHN1cmZhY2UpCgojIyMgUzZCIFBhcnRpY2xlIHNpemUgZGlzdHJpYnV0aW9uIHZzIGRlcHRoCmBgYHtyfQpQbG90UFNERVAgPC0gdWRzICU+JSAKICBmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcHNkLCB5ID0gZGVwdGgsIGNvbCA9IHByb2plY3QsIHNoYXBlID0gcHJvamVjdCkpICsKIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcsIHNpemUgPSAyLCBzdHJva2UgPSAxKSArCiAgZ2VvbV9wYXRoKGFlcyh4ID0gcHNkX2dhbSkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IHBzZF9nYW0sIHhtaW4gPSBwc2RfZ2FtIC0gMiAqIHBzZF9zZWcsIHhtYXggPSBwc2RfZ2FtICsgMiAqIHBzZF9zZWcpLCBhbHBoYSA9IDAuMSkgKwpzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZ3JheTIwIiwgImJyb3duIikpICArCiAgc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcyA9IGMoMTo1KSkgKyBsYWJzKHkgPSAiIiwgeCA9ICJQYXJ0aWNsZSBTaXplIERpc3RyaWJ1dGlvbiBTbG9wZSIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBQaG90aWNCYXNlLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gT01aQmFzZSwgY29sb3IgPSAiZGFya2JsdWUiKSAKClBsb3RQU0RFUApgYGAKCiMjIyBGaWd1cmUgUzYgQ29tYmluZWQKCmBgYHtyIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gNH0KcGxvdF9ncmlkKFBsb3ROUGFydGljbGVzRVAsIFBsb3RQU0RFUCwgcmVsX3dpZHRocyA9IGMoMiwzKSwgbGFiZWxzID0gYygiQSIsICJCIikpCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNBbmRQU0RfRVROUFZzUDE2LnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9QYXJ0aWNsZXNBbmRQU0RfRVROUFZzUDE2LnBuZyIpCmBgYAoKIyBGaWd1cmUgUzcKCkxhcmdlIGFuZCBzcGFsbCBwYXJ0aWNsZSBudW1iZXIsIGZsdXggYW5kIHNpemUKCmBgYHtyfQptYWluUGFydGljbGVDb21wb25lbnRzIDwtIGJkcyAlPiUKICBmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgc2VsZWN0KHByb2plY3QsIHByb2ZpbGUsIGRlcHRoLAogICAgICAgICB0b3RfbnBhcnRpY2xlcywgc21hbGxfbnBhcnRpY2xlcywgYmlnX25wYXJ0aWNsZXMsCiAgICAgICAgIHRvdF9wc2QgPSBwc2QsIHNtYWxsX3BzZCwgYmlnX3BzZCwKICAgICAgICAgdG90X2ZsdXhfZml0LCBzbWFsbF9mbHV4X2ZpdCwgYmlnX2ZsdXhfZml0KSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKCJwcm9qZWN0IiwgInByb2ZpbGUiLCAiZGVwdGgiKSkgJT4lCiAgc2VwYXJhdGUobmFtZSwgYygic2l6ZSIsICJtZWFzIikpICU+JQogIG11dGF0ZShtZWFzID0gcmVjb2RlKG1lYXMsIG5wYXJ0aWNsZXMgPSAicGFydGljbGVzL0wiKSkgJT4lCiAgbXV0YXRlKG1lYXMgPSBmYWN0b3IobWVhcywgbGV2ZWxzID0gYygicGFydGljbGVzL0wiLCAiZmx1eCIsICJwc2QiKSkpCgpQbG90Rmx4IDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzICE9ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZSB+IG1lYXMsIHNjYWxlcyA9ICJmcmVlX3giKSArIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgc2NhbGVfeF9sb2cxMCgpICsgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIHN0cmlwLmJhY2tncm91bmQueSA9IGVsZW1lbnRfYmxhbmsoKSwgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDAsNyw3KSwgInB0IikpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoUDE2ID0gImJyb3duIiwgRVROUCA9ICJncmF5MjAiKSkgKyBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IFBob3RpY0Jhc2UsIGNvbG9yID0gImRhcmtncmVlbiIpCgpQbG90UFNEIDwtIG1haW5QYXJ0aWNsZUNvbXBvbmVudHMgJT4lIAogIGZpbHRlcihtZWFzID09ICJwc2QiKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHZhbHVlLCBjb2wgPSBwcm9qZWN0LCBzaGFwZSA9IHByb2plY3QpKSArIGZhY2V0X2dyaWQoc2l6ZX5tZWFzLCBzY2FsZXMgPSAiZnJlZV94IikgKyBnZW9tX3BvaW50KHNpemUgPSAyKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLCBwbG90Lm1hcmdpbiA9IHVuaXQoYyg3LDcsMjYuNSwwKSwgInB0IikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhQMTYgPSAiYnJvd24iLCBFVE5QID0gImdyYXkyMCIpKSArICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxOjUpKSArICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBQaG90aWNCYXNlLCBjb2xvciA9ICJkYXJrZ3JlZW4iKQoKcGxvdF9ncmlkKFBsb3RGbHgsIFBsb3RQU0QsIHJlbF93aWR0aHMgPSBjKDMsIDIpKQoKZ2dzYXZlKCJmaWd1cmVzL0JpZ1ZzU21hbGwuc3ZnIikKZ2dzYXZlKCJmaWd1cmVzL0JpZ1ZzU21hbGwucG5nIikKYGBgCgpGbHV4IHNtYWxsIGFuZCBmbHV4IHRvdCB0cmFjayBzbyBjbG9zZWx5IGJlY2F1c2UgcGFydGljbGUgZnJhY3RhbCBkaW1lbnNpb24gYWxwaGEsIHBsdXMgZmx1eCBmcmFjdGFsIGRpbWVuc2lvbiwgZ2FtbWEgPiB8cHNkfC4gc2luY2UgdGhlIHNpemUgZGlzdHJpYnV0aW9uIG9mIHRoZSBmbHV4IHNvdWxkIGJlIFBTRCArIGFnIChwc2QgaXMgbmVnYXRpdmUgaW4gdGhpcyBjYXNlKS4gWW8gdWNhbiBzZWUgdGhlIHZhcmlhbmNlIGF0IHRoZSBvbmUgZGVwdGggd2hlcmUgcHNkIGlzIGZsYXRlc3QgYXQgdGhlIHZlcnkgdG9wLgoKCiMgRmlndXJlIFM0CkV4YW1wbGUgcGFydGljbGUgc2l6ZSBkaXN0cmlidXRpb25zCgpgYGB7cn0KZWdfZGF0YWxpbmUgPC0gYmRzICU+JSAKICBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIsIGRlcHRoID09IDE2Mi41KQplZ19zbG9wZSA9ICBlZ19kYXRhbGluZSAlPiUgcHVsbChwc2QpCmVnX2ljcCA9IGVnX2RhdGFsaW5lICU+JSBwdWxsKGljcCkKZWdfdm9sID0gZWdfZGF0YWxpbmUgJT4lIHB1bGwodm9sKQoKZWdfZGF0YWJsb2NrIDwtIGJlcyAlPiUKICBmaWx0ZXIocHJvZmlsZSA9PSAic3RuXzA0MyIsIGRlcHRoID09IDE2Mi41KQoKCmVnX2xiID0gZWdfZGF0YWJsb2NrJGxiCmVnX2JpbnNpemUgPSBlZ19kYXRhYmxvY2skYmluc2l6ZQplZ19ubnAgPSBleHAoZWdfaWNwICsgbG9nKGVnX2xiKSAqIGVnX3Nsb3BlKQoKZWdfbnAgPSBlZ19ubnAgKiBlZ19iaW5zaXplCmVnX3RwID0gZWdfbnAgKiBlZ192b2wKZWdfZGYgPC0gdGliYmxlKGxiID0gZWdfbGIsIG5fbnBhcnRpY2xlcyA9IGVnX25ucCwgbnBhcnRpY2xlcyA9IGVnX25wLCBUb3RhbFBhcnRpY2xlcyA9IGVnX3RwKQoKCkVnTk5QIDwtIGVnX2RhdGFibG9jayAlPiUKICBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IG5fbnBhcnRpY2xlcykpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgCiAgZ2VvbV9wYXRoKGRhdGEgPSBlZ19kZikgKyBsYWJzKHkgPSAiQmluc2l6ZSAmIFZvbHVtZSBOb3JtYWxpemVkIFxuIFBhcnRpY2xlcyAoIy9ML21tKSIsIHggPSAiU2l6ZSAobW0pIikKCkVnTlAgPC0gZWdfZGF0YWJsb2NrICU+JQogIGdncGxvdChhZXMoeCA9IGxiLCB5ID0gbnBhcnRpY2xlcykpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgCiAgZ2VvbV9wYXRoKGRhdGEgPSBlZ19kZikgKyBsYWJzKHkgPSAiTm9ybWFsaXplZCBQYXJ0aWNsZXMiICwgeCA9ICJTaXplIChtbSkiKQoKRWdUUCA8LSBlZ19kYXRhYmxvY2sgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBUb3RhbFBhcnRpY2xlcykpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfeV9sb2cxMCgpICsgCiAgZ2VvbV9wYXRoKGRhdGEgPSBlZ19kZikgKyBsYWJzKCB5ID0gIlRvdGFsIFBhcnRpY2xlcyBPYnNlcnZlZCAoIykiLCB4ID0gIlNpemUgKG1tKSIpCgpwbG90X2dyaWQoRWdOTlAsIEVnVFAsIGxhYmVscyA9IGMoIkEiLCAiQiIpKQpnZ3NhdmUoImZpZ3VyZXMvRXhhbXBsZVBTRDE2M20ucG5nIikKZ2dzYXZlKCJmaWd1cmVzL0V4YW1wbGVQU0QxNjNtLnN2ZyIpCgpgYGAKCiMgRmlndXJlIDVBCkZsdXggYXR0ZW51YXRpb24gd2l0aCByZXNwZWN0IG90IGRlcHRoIGFuZCB0aW1lLiBBbGwgZXh0cmFwb2xhdGVkIGZyb20gdGhlIFVWUCBhbmQgdHJhcHMgY29tYmluZWQuCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpzY2llbnRpZmljXzEwIDwtIGZ1bmN0aW9uKHgpIHtwYXJzZSh0ZXh0PWdzdWIoImVcXCsqIiwgIiAlKiUgMTBeIiwgc2NhbGVzOjpzY2llbnRpZmljX2Zvcm1hdCgpKHgpKSkgfQpzY2llbnRpZmljXzEwX2IgPC0gZnVuY3Rpb24oeCkge3BhcnNlKHRleHQ9Z3N1YigiZVxcKyoiLCAiICUqJSAxMF4iLCBzY2FsZXM6OnNjaWVudGlmaWNfZm9ybWF0KCkoeCkpKSB9CgpzY2llbnRpZmljXzEwX2MgPC0gZnVuY3Rpb24oeCkgewogICAgeG91dCA8LSBnc3ViKCIxZSIsICIxMF57IiwgZm9ybWF0KHgpLGZpeGVkPVRSVUUpCiAgICB4b3V0IDwtIGdzdWIoInstMCIsICJ7LSIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigieysiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gZ3N1YigiezAiLCAieyIsIHhvdXQsZml4ZWQ9VFJVRSkKICAgIHhvdXQgPC0gcGFzdGUoeG91dCwifSIsc2VwPSIiKQogICAgcmV0dXJuKHBhcnNlKHRleHQ9eG91dCkpCiAgICAKfQoKc2NhbGVfeF9sb2cxMG5pY2UgPC0gZnVuY3Rpb24obmFtZT1OVUxMLG9tYWc9c2VxKC0xMCwyMCksLi4uKSB7CiAgICBicmVha3MxMCA8LSAxMF5vbWFnCiAgICBzY2FsZV94X2xvZzEwKGJyZWFrcz1icmVha3MxMCxsYWJlbHM9c2NpZW50aWZpY18xMF9jKGJyZWFrczEwKSwuLi4pCn0KCgojaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTA3NjIyODcvaG93LWNhbi1pLWZvcm1hdC1heGlzLWxhYmVscy13aXRoLWV4cG9uZW50cy13aXRoLWdncGxvdDItYW5kLXNjYWxlcwojamFjb2JfbWFnbml0dWRlIDwtIGZ1bmN0aW9uKHgpe2V4cHJlc3Npb24oMTBecm91bmQobG9nMTAoeCkpKX0KCmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdEZseCA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9sb2cxMG5pY2UoKSsKICAjc2NhbGVfeF9sb2cxMCgpICsgCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciBvZiBEYXkiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpLCBsaW1pdHMgPSBjKDAsIDI0KSkgKwogIAogIGxhYnMoeCA9IGJxdW90ZShTbW9vdGhlZH5GbHV4fijCtW1vbH5DL21eMi9kKSksIHkgPSAiRGVwdGggKG0pIikgKwogICNsYWJzKHggPSAibW9vIiwgeSA9ICJEZXB0aCAobSkiKSArCiAgZ2VvbV9yZWN0KGRhdGEgPSBkYXRhLmZyYW1lKHByb2plY3QgPSAiRVROUCIpLCBhZXMoeG1pbiA9IDIwLCB4bWF4ID0gMTgwLCB5bWluID0gNzUsIHltYXggPSA1MDApLCBjb2xvdXIgPSAicmVkIiwgZmlsbCA9IE5BLCBpbmhlcml0LmFlcyA9IEZBTFNFKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAuMyksIGxlZ2VuZC5zcGFjaW5nID0gdW5pdCguMSwgImNtIikpICsKICAgZ2VvbV9zZWdtZW50KGFlcyh5ID0gUGhvdGljQmFzZSwgeWVuZCA9IFBob3RpY0Jhc2UsIHggPSAyMCwgeGVuZCA9IDUwMCksIGNvbG9yID0gImRhcmtncmVlbiIsIHN0cm9rZSA9IDAuNSkrCiAgIGdlb21fc2VnbWVudChhZXMoeSA9IE9NWkJhc2UsIHllbmQgPSBPTVpCYXNlLCB4ID0gMjAsIHhlbmQgPSA1MDApLCBjb2xvciA9ICJkYXJrYmx1ZSIsIHN0cm9rZSA9IDAuNSkgIysKICAjZ2VvbV9zZWdtZW50KGFlcyh5ID0gRFZNQmFzZSwgeWVuZCA9IERWTUJhc2UsIHggPSAyMCwgeGVuZCA9IDUwMCksIGNvbG9yID0gImRhcmtnb2xkZW5yb2QiLCBsdHkgPSAiZGFzaGVkIiwgc3Ryb2tlID0gMC41KQogIAogICMrIGdlb21faGxpbmUoeWludGVyY2VwdCA9IE9NWkJhc2UsIGNvbG9yID0gImRhcmtibHVlIikKCgoKcGx0Rmx4Tm9MZWdlbmQgPC0gcGx0Rmx4ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpwbHRGbHhMZWdlbmQgPC0gZ2V0X2xlZ2VuZChwbHRGbHgpCgpwbHRGbHgKI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgojIyBGaWd1cmUgNUIKWm9vbWluZyBpbiBvbiB3aGVyZSB0aGUgYWN0aW9uIGlzIGhhcHBlbmluZwpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHRGbHhab29tIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiICYgZGVwdGggPD0gNTAwICYgZGVwdGggPj0gNzUpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gRmx1eF9TbW9vdGgsIHNoYXBlID0gZmFjdG9yKGRheSh0aW1lKSksIGZpbGwgPSBob3VyKHRpbWUpLCBncm91cCA9IGZhY3Rvcih0aW1lKSkpICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UoKSsKICAjc2NhbGVfeF9sb2cxMCgpICsKICBzY2FsZV94X2xvZzEwKGJyZWFrcyA9IGMoc2VxKGZyb20gPSAyMCwgdG8gPSA1MCwgYnkgPSAxMCksIHNlcShmcm9tID0gNjAsIHRvID0gMTgwLCBieSA9IDIwKSksIGxpbWl0cyA9IGMoMjAsIDE4MCkpICsKICAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJkYXJrZ3JlZW4iLCBtaWQgPSAiZ3JheTgwIiwgaGlnaCA9ICJwdXJwbGUiLCBtaWRwb2ludCA9IDEwKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKwpsYWJzKHggPSAiU21vb3RoZWQgRmx1eCIsIHkgPSAiRGVwdGgiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCmdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikKCnBsdEZseFpvb20KI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgojIyBGaWd1cmUgNUMKUmF0ZSBvZiBjaGFuZ2Ugb2YgZmx1eCwgdGFrZW4gdG8gdGhlIGZpZnRoIHJvb3Qgc28gb25lIGNhbiBzZWUgcGF0dGVybnMuCgpgYGB7ciBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHREZWx0YTMgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiRVROUCIpICU+JSAjZmlsdGVyKERGUCA+IDEpICU+JSAjZmlsdGVyKHByb2ZpbGUgJWluJSBjKCJzdG5fMDQzIiwgInAxNm5fMTAwIikpICU+JQogIGdncGxvdChhZXMoeSA9IGRlcHRoLCB4ID0gcHJhY21hOjpudGhyb290KERGL0RaLCA1KSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMiwgc3Ryb2tlID0gMSkrCiAgI2dlb21fcGF0aCgpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTIuMSwgLjYpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgbGFicyh4ID0gYnF1b3RlKChERi9EWileezEvNX1+KMK1bW9sQy9tXjMvZCleezEvNX0pLCB5ID0gIkRlcHRoIChtKSIpICsgdGhlbWUobGVnZW5kLnBvcyA9ICJub25lIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gUGhvdGljQmFzZSwgY29sb3IgPSAiZGFya2dyZWVuIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IE9NWkJhc2UsIGNvbG9yID0gImRhcmtibHVlIikgCiAgI2dlb21faGxpbmUoeWludGVyY2VwdCA9IERWTUJhc2UsIGNvbG9yID0gImRhcmtnb2xkZW5yb2QiLCBsdHkgPSAiZGFzaGVkIikKICAjbGFicyh4ID0gIihERi9EWikgXiAxLzUgKMK1bW9sIEMvbV4zL2QpIF4gMS81IikKCnBsdERlbHRhMwojcGxvdGx5OjpnZ3Bsb3RseShwbHQxcG9zKQpgYGAKCiMjIENvbWJpbmluZyB0aGUgcGxvdHMKCldpdGhpbiBwYW5lbCBkcmF3aW5nCgoKYGBge3IgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDV9CnBnVG9wIDwtIGdnZHJhdyhwbHRGbHhOb0xlZ2VuZCAKICAgICAgICkgKwogIGRyYXdfcGxvdChwbHRGbHhab29tLCAuNCwgLjI1LCAuNTUsIC42MCkgKwogIGRyYXdfcGxvdF9sYWJlbCgKICAgIGMoIiIsIkIiKSwKICAgIGMoLjA1LCAwLjU1KSwKICAgIGMoMSwgMC44NSksCiAgICBzaXplID0gMTYKICApCnBnVG9wCmBgYApwZ0JvdHRvbSA8LSBwbG90X2dyaWQocGx0RGVsdGEzLCBwbHRGbHhMZWdlbmQgLCByZWxfd2lkdGhzID0gYygzLCAxKSwgbGFiZWxzID0gYygiQyIsICIiKSwgbGFiZWxfc2l6ZSA9IDE0KQoKCgoKSSBkb24ndCBrbm93IHdoYXRzIGdvaW5nIG9uIGJlbG93IGhlcmUKCmBgYHtyIGZpZy5oZWlnaHQgPSA5LCBmaWcud2lkdGggPSA1fQpwZ0JvdHRvbSA8LSBwbHREZWx0YTMgICsgZ2VvbV9yZWN0KGFlcyh4bWluID0gLTIsIHhtYXggPSAtMS4xNSwgeW1pbiA9IDE3MCwgeW1heCA9IDEwMDApLCBjb2xvdXIgPSAiZ3JheTUwIiwgZmlsbCA9ICJ3aGl0ZSIsIGluaGVyaXQuYWVzID0gRkFMU0UpICsgZHJhd19wbG90KHBsdEZseExlZ2VuZCAsIC0xLjksIC01NzUsIC43KQpwZ0JvdGggPC0gcGxvdF9ncmlkKHBnVG9wICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIHBnQm90dG9tICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwgMCwgMCwgMCksIHVuaXRzID0gImNtIikpLAogICAgICAgICAgICAgICAgICAgIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoNCwgNCksIGxhYmVscyA9IGMoIkEiLCAiQyIpLCBsYWJlbF9zaXplID0gMTYpCnBnQm90aAoKZ2dzYXZlKCJmaWd1cmVzL0ZsdXhEZWVwRGl2ZS5wbmciKQpnZ3NhdmUoImZpZ3VyZXMvRmx1eERlZXBEaXZlLnN2ZyIpCmBgYAoKCiMjIFN1bW1hcnkgc3RhdHMKVGVzdCBmb3IgZGF5IHRvIGRheSBhbmQgaG91cmx5IHZhcmlhYmlsaXR5IGluIHJhdGUgb2YgY2hhbmdlIG9mIGZsdXggKGZpZnRoIHJvb3QgdHJhbnNmb3JtZWQpCiAKClRoZXJlIGlzIHZhcmlhYmlsaXR5IHdpdGggcmVzcGVjdCB0byBkZXB0aCwgYW5kIGRheSBhbmQgaG91cgpEZXB0aCBwID0gMC4wMyBSXjIgPSAwLjA4OC4gQWRkIGFmZmVjdCBvZiBkYXkgIHAgPSAwLjAwNCwgZXh0cmEgUl4yID0gMC4xMSwgQWRkIGFmZmVjdCBvZiBob3VyIHAgPSAwLjAyIGV4dHJhIFIyID0gMC4xMgoKYGBge3J9CmJkc0FkZFRpbWUgPC0gYmRzICU+JSAKICBtdXRhdGUoSG91ciA9IGhvdXIodGltZSkgKyBtaW51dGUodGltZSkvNjAsIERheSA9IGRheSh0aW1lKSArIGhvdXIodGltZSkvMjQgKyBtaW51dGUodGltZSkvMjQvNjApCgpERkcxIDwtIGdhbShwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMjUwICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpERkcyIDwtIGdhbShwcmFjbWE6Om50aHJvb3QoREYvRFosIDUpIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAyNTAgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCkRGRzMgPC0gZ2FtKHByYWNtYTo6bnRocm9vdChERi9EWiwgNSkgfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gMjUwICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpERkdfRGF5T25seSA8LSBnYW0ocHJhY21hOjpudGhyb290KERGL0RaLCA1KSB+ICBzKERheSwgayA9IDMpLCBkYXRhID0gYmRzQWRkVGltZSAlPiUgZmlsdGVyKGRlcHRoID49IDI1MCAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKREZHX05vRmlmdGggPC0gZ2FtKHByYWNtYTo6bnRocm9vdChERi9EWiwgMSl+IHMoZGVwdGgsIGsgPSAzKSArIHMoRGF5LCBrID0gMykgKyBzKEhvdXIsIGsgPSA0LCBicyA9ICJjYyIpLCBrbm90cyA9IGxpc3QoSG91ciA9IGMoMCwgMjQpKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSAyNTAgJiBkZXB0aCA8PTUwMCAmIHByb2plY3QgPT0gIkVUTlAiKSkKCnN1bW1hcnkoREZHMSkKCnN1bW1hcnkoREZHX0RheU9ubHkpCgpzdW1tYXJ5KERGR19Ob0ZpZnRoKQoKCgoKIyBzdW1tYXJ5KERGRzIpCiMgc3VtbWFyeShERkczKQojIAojIHN1bW1hcnkoREZHMSkkci5zcSAtIHN1bW1hcnkoREZHMikkci5zcQojIHN1bW1hcnkoREZHMikkci5zcSAtIHN1bW1hcnkoREZHMykkci5zcQojIHN1bW1hcnkoREZHMykkci5zcQpgYGAKClRpbWUgaXMgbm93IGNvbnRpbnVvdXMgZGF5IGFuZCBob3VyCgpQbG90IG9mIHRoZSBnYW1zIGFib3ZlCmBgYHtyIGZpZy5oZWlnaHQgPSA4LCBmaWcud2lkdGggPSAxMH0KI3Bsb3QubmV3KCkKRmx1eEdhbVBsb3QgPC0gZnVuY3Rpb24oKXsKICBwYXIobWZyb3cgPSBjKDIsMikpCiAgcGxvdChERkcxKQogIGFibGluZShoID0gMCwgY29sID0gImdyYXkzMCIsIGx3ZCA9IDIpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJDIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBhYmxpbmUoaCA9IDAsIGNvbCA9ICJncmF5MzAiLCBsd2QgPSAyKQogIG10ZXh0KGV4cHJlc3Npb24oYm9sZCgiQSIpKSwgc2lkZSA9IDMsIGxpbmUgPSAwLCBhZGogPSAwLCBjZXggPSAyKQogIHBhcihtZmcgPSBjKDEsMikpCiAgYWJsaW5lKGggPSAwLCBjb2wgPSAiZ3JheTMwIiwgbHdkID0gMikKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkIiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKfQoKRmx1eEdhbVBsb3QoKQoKcG5nKGZpbGVuYW1lID0gIi4vZmlndXJlcy9GbHV4R2FtUGxvdC5wbmciLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIsIHJlcyA9IDIwMCkKRmx1eEdhbVBsb3QoKQpkZXYub2ZmKCkKYGBgCgoKCiMgRmlndXJlIDcKIyMgRGlmZmVyZW5jZSBmcm9tIG1vZGVsIGV4cGVjdGF0aW9ucwoKKHUgbW9sIEMgLyBtXjMgLyBkYXkpCmBgYHtyIGZpZy53aWR0aCA9IDYsIGZpZy5oZWlnaHQgPSA0fQpkaXNhZ0ZpZyA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3Qob3Nwc0RaLCAzKSwgc2hhcGUgPSBmYWN0b3IoZGF5KHRpbWUpKSwgZmlsbCA9IGhvdXIodGltZSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgKyBnZW9tX3BvaW50KHNpemUgPSAyKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsIDEpKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKyAgIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsKICAjbGFicyh4ID0gYnF1b3RlKCJPYnNlcnZlZCAtIE1vZGVsZWQgU21hbGwgUGFydGljbGUgRmx1eCJ+KM68bW9sL21eMy9kYXkpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgbGFicyh4ID0gcGFzdGUoIkRldmlhdGlvbiBmcm9tIE1vZGVsIiwgZXhwcmVzc2lvbigozrxtb2wvbV4zL2RheSkpKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciBvZiBEYXkiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IFBob3RpY0Jhc2UsIGNvbG9yID0gImRhcmtncmVlbiIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gT01aQmFzZSwgY29sb3IgPSAiZGFya2JsdWUiKSAjKwogICNnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBEVk1CYXNlLCBjb2xvciA9ICJkYXJrZ29sZGVucm9kIiwgbHR5ID0gImRhc2hlZCIpCmRpc2FnRmlnCiNnZ3NhdmUoIi4uZmlndXJlcy9GbHV4U2l6ZVNoaWZ0LnN2ZyIKCiBnZ3NhdmUoImZpZ3VyZXMvRmx1eFNpemVTaGlmdC5wbmciKQogZ2dzYXZlKCJmaWd1cmVzL0ZsdXhTaXplU2hpZnQuc3ZnIikKYGBgCgojIyBTdW1tYXJ5IHN0YXRpc3RpY3MKCmBgYHtyfQojIGJkc0FkZFRpbWUgPC0gYmRzICU+JQojICAgbXV0YXRlKEhvdXIgPSBob3VyKHRpbWUpLCBEYXkgPSBkYXkodGltZSkpCgpiZHNBZGRUaW1lIDwtIGJkcyAlPiUKICBtdXRhdGUoSG91ciA9IGhvdXIodGltZSkgKyBtaW51dGUodGltZSkvNjAsIERheSA9IGRheSh0aW1lKSArIGhvdXIodGltZSkvMjQgKyBtaW51dGUodGltZSkvMjQvNjApCgpPWkcxIDwtIGdhbShvc3BzRFogfiBzKGRlcHRoLCBrID0gMykgKyBzKERheSwgayA9IDMpICsgcyhIb3VyLCBrID0gNCwgYnMgPSAiY2MiKSwga25vdHMgPSBsaXN0KEhvdXIgPSBjKDAsIDI0KSksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gUGhvdGljQmFzZSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKT1pHMiA8LSBnYW0ob3Nwc0RaIH4gcyhkZXB0aCwgayA9IDMpICsgcyhEYXksIGsgPSAzKSwgZGF0YSA9IGJkc0FkZFRpbWUgJT4lIGZpbHRlcihkZXB0aCA+PSBQaG90aWNCYXNlICYgZGVwdGggPD01MDAgJiBwcm9qZWN0ID09ICJFVE5QIikpCgpPWkczIDwtIGdhbShvc3BzRFogfiBzKGRlcHRoLCBrID0gMyksIGRhdGEgPSBiZHNBZGRUaW1lICU+JSBmaWx0ZXIoZGVwdGggPj0gUGhvdGljQmFzZSAmIGRlcHRoIDw9NTAwICYgcHJvamVjdCA9PSAiRVROUCIpKQoKc3VtbWFyeShPWkcxKQpzdW1tYXJ5KE9aRzIpCnN1bW1hcnkoT1pHMykKCnN1bW1hcnkoT1pHMSkkci5zcSAtIHN1bW1hcnkoT1pHMikkci5zcSAjIEV4dHJhIGZyb20gSG91cgpzdW1tYXJ5KE9aRzIpJHIuc3EgLSBzdW1tYXJ5KE9aRzMpJHIuc3EgIyBFeHRyYWZyb20gRGF5CnN1bW1hcnkoT1pHMykkci5zcSAjIERlcHRoCmBgYAoKUGxvdCBvZiB0aG9zZSBnYW1zIEZpZ3VyZSBTMTAKCmBgYHtyfQpPU01TR2FtUGxvdCA8LSBmdW5jdGlvbigpewogIHBhcihtZnJvdyA9IGMoMiwyKSkKICBwbG90KE9aRzEpCiAgCiAgcGFyKG1mZyA9IGMoMSwxKSkKICBhYmxpbmUoaCA9IDAsIGNvbCA9ICJncmF5MzAiLCBsd2QgPSAyKQogIG10ZXh0KGV4cHJlc3Npb24oYm9sZCgiQSIpKSwgc2lkZSA9IDMsIGxpbmUgPSAwLCBhZGogPSAwLCBjZXggPSAyKQogIHBhcihtZmcgPSBjKDEsMikpCiAgYWJsaW5lKGggPSAwLCBjb2wgPSAiZ3JheTMwIiwgbHdkID0gMikKICBtdGV4dChleHByZXNzaW9uKGJvbGQoIkIiKSksIHNpZGUgPSAzLCBsaW5lID0gMCwgYWRqID0gMCwgY2V4ID0gMikKICBwYXIobWZnID0gYygyLDEpKQogIGFibGluZShoID0gMCwgY29sID0gImdyYXkzMCIsIGx3ZCA9IDIpCiAgbXRleHQoZXhwcmVzc2lvbihib2xkKCJDIikpLCBzaWRlID0gMywgbGluZSA9IDAsIGFkaiA9IDAsIGNleCA9IDIpCn0KCk9TTVNHYW1QbG90KCkKCnBuZyhmaWxlbmFtZSA9ICIuL2ZpZ3VyZXMvT1NNU0dhbVBsb3QucG5nIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gOCwgdW5pdHMgPSAiaW4iLCByZXMgPSAyMDApCk9TTVNHYW1QbG90KCkKCmRldi5vZmYoKQpgYGAKCgoKCiMgRmlndXJlIDMKIyMgVHJhcCBkYXRhCmBgYHtyfQp0cmFwRmx1eDMgPC0gcmVhZF9jc3YoImRhdGFPdXQvZmx1eE1TX2Rpc3RpbGxlZC5jc3YiKQpVVlBGbHV4Q29tYiA8LSByZWFkX2NzdigiZGF0YU91dC9Db21iaW5lZFByb2ZpbGVGbHV4RXN0X0RTLmNzdiIpClVWUEZsdXhPRSA8LSByZWFkX2NzdigiZGF0YU91dC9PYnNlcnZlZFZzRXhwZWN0ZWRGbHV4LmNzdiIpCmBgYAoKCgpgYGB7cn0KCmZsdXhNU19kaXN0aWxsZWRfdG9QbG90IDwtIHRyYXBGbHV4MyAlPiUKICBtdXRhdGUoU2FtcGxlVHlwZSA9IHJlY29kZShTYW1wbGVUeXBlLCBgcGx1cy5wYCA9ICJwbHVzLXBhcnRpY2xlcyIsIHRvcCA9ICJ0b3AtY29sbGVjdG9yIikpCmBgYAoKUmVtb3ZlIHRyYXBzIHdoZXJlIG1hc3Mgc3BlYyBkaWRuJ3Qgd29yayBjb3JyZWN0bHkKMi0xNyAxNTAKMS0xMiA3M20KMS0xMiAxNDgKMi0xNCAxMDAKfChUcmFwSUQgPT0gIjItMTciICYgRGVwdGggPT0gMTUwKQpgYGB7cn0KZmx1eE1TX2Rpc3RpbGxlZF90b1Bsb3QyIDwtIGZsdXhNU19kaXN0aWxsZWRfdG9QbG90ICU+JQogZmlsdGVyKCEoKFRyYXBJRCA9PSAiMS0xMiIpIHwgKFRyYXBJRCA9PSAiMi0xNCIgJiBEZXB0aCA9PSAxMDApfChUcmFwSUQgPT0gIjItMTciICYgRGVwdGggPT0gMTUwKSkpCiNmbHV4TVNfZGlzdGlsbGVkX3RvUGxvdDIKYGBgCgoKVHJhcHMgd2hlcmUgbWFzcyBzcGVjIGRpZG4ndCB3b3JrLgoKCmBgYHtyfQpVVlBGbHV4UGxvdDAwIDwtIFVWUEZsdXhDb21iICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCkpICArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMjAwKSkgKwogIGdlb21fcG9pbnQoYWVzKHkgPSBEZXB0aCwgeCA9IENfZmx1eF91bW9sLCBzaGFwZSA9IFRyYXBUeXBlLCBJRCA9IFRyYXBJRCksCiAgICAgICAgICAgICBjb2xvdXIgPSAiYmxhY2siLCBzdHJva2UgPSAxLCBzaXplID0gNSwgZGF0YSA9IGZsdXhNU19kaXN0aWxsZWRfdG9QbG90MikgKwogIGdlb21fbGluZShhZXMoeCA9IEZsdXgpLCBzaXplID0gMSwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IC0xLCB5ID0gLTEsIHNpemUgPSAiVVZQIEVzdGltYXRlIikpICsgIyBkdW1teSBwb2ludCBmb3IgdGhlIGxlZ2VuZAogIGdlb21fcG9pbnQoYWVzKHggPSB0b3RfZmx1eDIpLCBzaXplID0gMywgc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiLCBmaWxsID0gImJsYWNrIiwgZGF0YSA9IFVWUEZsdXhPRSkgKwpzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygyNSwgMjIpKSsKICBzY2FsZV9zaXplX21hbnVhbCh2YWx1ZXMgPSAxLCBuYW1lID0gIiIpICsKICB5bGFiKCJEZXB0aCAobSkiKSArCiAgI3hsYWIoZXhwcmVzc2lvbihGbHV4IMK1bW9sQy9tXjIvZGF5KSkgKwogIHhsYWIoZXhwcmVzc2lvbihwYXN0ZSgieCBheGlzICIsIHJpbmcoQSleMikpKSArCiAgeGxhYihleHByZXNzaW9uKHBhc3RlKCJGbHV4ICjCtSBtb2wgQy8iLCBtXjIsICIvZGF5KSIpKSkgKwogIAogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2hhcGUgPSAyMSkpKSArCiAgdGhlbWVfY293cGxvdCgpICsgCiAgdGhlbWUoCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygwLjUsIDAuNCksCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuNSksCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMTAsIDUsIDEwLCA1KQogICkgCiMgVVZQRmx1eFBsb3QgPC0gVVZQRmx1eFBsb3QwMCArCiMgICBnZW9tX3JlY3QoZGF0YSA9IGRhdGEuZnJhbWUocHJvamVjdCA9ICJFVE5QIiksIGFlcyh4bWluID0gMTUsIHhtYXggPSAzMiwgeW1pbiA9IDQ1LCB5bWF4ID0gMTk1KSwgY29sb3VyID0gInJlZCIsIGZpbGwgPSBOQSwgaW5oZXJpdC5hZXMgPSBGQUxTRSkKClVWUEZsdXhQbG90MDAKCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9GaXR0ZWRGbHV4LnN2ZyIpCmBgYAoKIyBGaWd1cmUgUzIKIyMgRXhhbXBsZSBwYXJ0aWNsZSBzaXplIGRpc3RyaWJ1dGlvbgoKYGBge3IgZmlnLndpZHRoPSAxMH0KVFBQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBUb3RhbFBhcnRpY2xlcywgeSA9IGRlcHRoLCBjb2wgPSBsb2cobGIpLCBncm91cCA9IGxiKSkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKyBnZW9tX3BvaW50KCkgKyBzY2FsZV94X2xvZzEwKCkgKyBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKSArIGdlb21fcGF0aCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSkgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1KSArIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlRvdGFsUGFydGljbGVzIE9ic2VydmVkICgjKSIpCgpubnBQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBuX25wYXJ0aWNsZXMsIHkgPSBkZXB0aCwgY29sID0gbG9nKGxiKSwgZ3JvdXAgPSBsYikpICsgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpICsgZ2VvbV9wb2ludCgpICsgc2NhbGVfeF9sb2cxMCgpICsgc2NhbGVfY29sb3JfdmlyaWRpc19jKCkgKyBnZW9tX3BhdGgoKSArCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDEpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNSkgKwogIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIkJpbnNpemUgYW5kIFZvbHVtZSBOb3JtYWxpemVkIFBhcnRpY2xlcyAoIy9ML21tKSIpCgpGaXRQbG90IDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gInN0bl8wNDMiKSAlPiUgZ3JvdXBfYnkobGIpICU+JSBnZ3Bsb3QoYWVzKHggPSBubnBfc21vb3RoLCB4bWluID0gbm5wX2xvd2VyLCB4bWF4ID0gbm5wX3VwcGVyLCB5ID0gZGVwdGgsIGNvbCA9IGxvZyhsYiksIGdyb3VwID0gbGIpKSArIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsgZ2VvbV9wYXRoKCkgKwogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDUpICsKICBsYWJzKHkgPSAiRGVwdGggKG0pIiwgeCA9ICJTbW9vdGhlZCAtIE5vcm1hbGl6ZWQgUGFydGljbGVzICgjL0wvbW0pIikgKyBnZW9tX2Vycm9yYmFyKHdpZHRoID0gMTAsIGFscGhhID0gMC41KQoKbnBMZWdlbmQgPC0gZ2V0X2xlZ2VuZChGaXRQbG90ICsgdGhlbWUobGVnZW5kLmJveC5tYXJnaW4gPSBtYXJnaW4oMCwgMCwgNDAsIDIwMCkpICsgbGFicyhjb2wgPSBleHByZXNzaW9uKGxvZ1tlXShTaXplIChtbSkpKSkpCgpwbG90X2dyaWQoCiAgVFBQbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBubnBQbG90ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSwKICBucExlZ2VuZCAsCiAgRml0UGxvdCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiksIAogIGxhYmVscyA9IGMoIkEiLCAiQiIsICIiLCAiQyIpCikKCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnN2ZyIpCmdnc2F2ZSgiZmlndXJlcy9BbGxQYXJ0aWNsZVNpemVzLnBuZyIpCmBgYAoKCiMgRmlndXJlIDYKIyMgV2ViZXIgQmlhbmNoaSBGaWdzCgojIyMgSnVzdCBzdGF0aW9uIDA0MwoKV2UgYXJlIHNtb290aGluZyB0aGUgc3RhdGlvbiAwNDMgZGF0YSwgd2l0aCByZXNwZWN0IHRvIGRlcHRoIGFuZCB0aW1lLgpXZSBhcmUgdXNpbmcgdGhpcyBzdGF0aW9uIGJlY2F1c2UgaXQgaXMgdGhlIG9ubHkgb25lIHRvIGV4dGVuZCBwYXN0IDIwMDBtLiBXZSBmaW5kIHRoYXQgdGhlIG90aGVyIHByb2ZpbGVzIHNlZW0gdG8gZ2l2ZSBzdHJhbmdlIHZhbHVlcyBuZWFyIHRoZSBlbmRzIG9mIHRoZSByYW5nZXMgb2YgdGhlIGdhbXMuCgpgYGB7cn0KU2FtZUdhbSA8LSBnYW0oVG90YWxQYXJ0aWNsZXMgfnMobG9nKGxiKSwgbG9nKGRlcHRoKSksIG9mZnNldCA9IGxvZyh2b2wgKiBiaW5zaXplKSwgZmFtaWx5ID0gbmIoKSwKICAgIGRhdGEgPSBiZXMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJFVE5QIiwgZGVwdGggPD0gMjAwMCwgcHJvZmlsZSA9PSAic3RuXzA0MyIpKSAjIExvb2tzIGdvb2QhCmBgYAoKYGBge3J9CmdhbS5jaGVjayhTYW1lR2FtKQpgYGAKCmBgYHtyfQpiZXNFIDwtIGJlcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiKQoKbGJfbmV3IDwtIGV4cChzZXEoZnJvbSA9IGxvZygwLjEpLCB0byA9IGxvZygyLjEpLCBieSA9IDAuMDUpKQp1Yl9uZXcgPC0gbGVhZChsYl9uZXcpCmJpbnNpemVfbmV3IDwtIHViX25ldyAtIGxiX25ldwoKbGJicyA8LSB0aWJibGUobGIgPSBsYl9uZXcsIHViID0gdWJfbmV3LCBiaW5zaXplID0gYmluc2l6ZV9uZXcpCgpFeHBhbmRlZCA8LSBleHBhbmRfZ3JpZChsYiA9IGV4cChzZXEoZnJvbSA9IGxvZygwLjEpLCB0byA9IGxvZygyKSwgYnkgPSAwLjA1KSksIGRlcHRoID0gc2VxKGZyb20gPSAyMCwgdG8gPSAyMDAwLCBieSA9IDIwKSwgdGltZSA9IGFzLmZhY3Rvcih1bmlxdWUoYmVzRSR0aW1lKSkpICU+JSBsZWZ0X2pvaW4obGJicywgYnkgPSAibGIiKQoKUHJlZCA8LSBleHAocHJlZGljdChTYW1lR2FtLCBFeHBhbmRlZCkpCmBgYAoKYGBge3J9ClRvUGxvdCA8LSBiaW5kX2NvbHMoRXhwYW5kZWQsIG5ucGFydGljbGVzID0gUHJlZCkgJT4lIG11dGF0ZSh0aW1lID0gYXMuY2hhcmFjdGVyKHRpbWUpKSAlPiUgbXV0YXRlKG5wYXJ0aWNsZXMgPSBubnBhcnRpY2xlcyAqIGJpbnNpemUpCmBgYAoKYGBge3J9CldCQ29sb3JNYXAgPC0gVG9QbG90ICU+JSBmaWx0ZXIobGIgPD0gMikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGIsIHkgPSBkZXB0aCwgZmlsbCA9IGxvZzEwKG5ucGFydGljbGVzKSwgeiA9IGxvZzEwKG5ucGFydGljbGVzKSkpICsgZ2VvbV90aWxlKCkgKyBzY2FsZV9maWxsX3ZpcmlkaXNfYyhuYW1lID0gZXhwcmVzc2lvbihsb2dbMTBdKFBhcnRpY2xlcy9tXjMvbW0pKSkgKyBzY2FsZV95X3JldmVyc2UoKSArIHNjYWxlX3hfbG9nMTAoKSArIGdlb21fY29udG91cihjb2xvciA9ICJibGFjayIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTYwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IE9NWkJhc2UsIGNvbG9yID0gImRhcmtibHVlIikgKyBsYWJzKHkgPSAiRGVwdGggKG0pIiwgeCA9ICJTaXplIChtbSkiKQpXQkNvbG9yTWFwCmBgYAoKYGBge3J9Cm1iR2FtIDwtIFRvUGxvdCAlPiUgZ3JvdXBfYnkoZGVwdGgpICAlPiUgbmVzdCgpICU+JQogIG11dGF0ZShtb2QgPSBtYXAoZGF0YSwgfmdhbShsb2cobm5wYXJ0aWNsZXMpIH4gbG9nKGxiKSwgZmFtaWx5ID0gZ2F1c3NpYW4oKSwgZGF0YSA9IC4pKSkgJT4lIAogIG11dGF0ZShwc2QgPSBtYXBfZGJsKG1vZCwgfnN1bW1hcnkoLikkcC5jb2VmZlsyXSkpIApgYGAKCgoKIyMgUGFydGljbGUgc2l6ZSBkaXN0cmlidXRpb24sIHNtb290aGVkIG92ZXIgYWxsIHN0YXRpb25zCgpgYGB7cn0KcFdCUFNEIDwtIG1iR2FtICU+JQogIGdncGxvdChhZXMoeCA9IHBzZCwgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAgT01aQmFzZSwgY29sb3IgPSAiZGFya2JsdWUiKSArIGxhYnMoeSA9ICJEZXB0aCAobSkiLCB4ID0gIlBhcnRpY2xlIFNpemUgRGlzdHJpYnV0aW9uIFNsb3BlIikKcFdCUFNECmBgYAoKIyBMYXJnZSBQYXJ0aWNsZSBCaW9tYXNzCmBgYHtyfQpQdWJEZiA8LSBUb1Bsb3QgJT4lIG11dGF0ZSh1YmlvbWFzcyA9IG5wYXJ0aWNsZXMgKiBsYiBeIGFnX2dsb2JhbCkgJT4lIGZpbHRlcihsYiA8IDAuNSkgJT4lIGdyb3VwX2J5KGRlcHRoKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gc3VtKHViaW9tYXNzKSkgJT4lIHVuZ3JvdXAoKQpwaG90aWNCaW9tYXNzIDwtIFB1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTY1LCBkZXB0aCA+PSAxNTUpICU+JSBzdW1tYXJpemUodWJpb21hc3MgPSBtZWFuKHViaW9tYXNzKSkgJT4lIHB1bGwodWJpb21hc3MpClB1YkRmIDwtIFB1YkRmICU+JSBtdXRhdGUobmJpb21hc3MgPSB1YmlvbWFzcy9waG90aWNCaW9tYXNzKQpwV0JTIDwtIFB1YkRmICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBuYmlvbWFzcywgeSA9IGRlcHRoKSkgKyBnZW9tX3BhdGgoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwxLjIpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGNvbG9yID0gImdyYXk1MCIpICsgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gT01aQmFzZSwgY29sb3IgPSAiZGFya2JsdWUiKSArIGxhYnMoIHggPSAiU21hbGwgcGFydGljbGUgbWFzcyAobm9ybS4pIikgICsgdGhlbWUoYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpwV0JTCmBgYAoKI1NtYWxsIFBhcnRpY2xlIEJpb21hc3MKYGBge3J9Ckx1YkRmIDwtIFRvUGxvdCAlPiUgbXV0YXRlKHViaW9tYXNzID0gbnBhcnRpY2xlcyAqIGxiIF4gYWdfZ2xvYmFsKSAlPiUgZmlsdGVyKGxiID49IDAuNSkgJT4lIGdyb3VwX2J5KHRpbWUsIGRlcHRoKSAlPiUgc3VtbWFyaXplKHViaW9tYXNzID0gc3VtKHViaW9tYXNzKSkgJT4lIHVuZ3JvdXAgJT4lIGdyb3VwX2J5KGRlcHRoKSAgJT4lIHN1bW1hcmlzZSh1YmlvbWFzcyA9IG1lYW4odWJpb21hc3MpKQpwaG90aWNCaW9tYXNzIDwtIEx1YkRmICU+JSBmaWx0ZXIoZGVwdGggPD0gMTY1LCBkZXB0aCA+PTE1NSkgJT4lIHN1bW1hcml6ZSh1YmlvbWFzcyA9IG1lYW4odWJpb21hc3MpKSAlPiUgcHVsbCh1YmlvbWFzcykKTHViRGYgPC0gTHViRGYgJT4lIG11dGF0ZShuYmlvbWFzcyA9IHViaW9tYXNzL3Bob3RpY0Jpb21hc3MpCnBXQkwgPC0gTHViRGYgJT4lIGdncGxvdChhZXMoeCA9IG5iaW9tYXNzLCB5ID0gZGVwdGgpKSArIGdlb21fcGF0aCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKyBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDE2MCwgY29sb3IgPSAiZGFya2dyZWVuIikgKyBsYWJzKCB4ID0gIkxhcmdlIHBhcnRpY2xlIG1hc3MgKG5vcm0uKSIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwgY29sb3IgPSAiZ3JheTUwIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJncmF5NTAiKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IE9NWkJhc2UsIGNvbG9yID0gImRhcmtibHVlIikgKyB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpCnBXQkwKYGBgCgojIyMgQ29tYmluZSB0aGUgdGhyZWUgbG93ZXIgcGFubmVscwpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQ9M30KV0JGaWc1IDwtIHBsb3RfZ3JpZChwV0JQU0QsIHBXQlMscFdCTCwgbnJvdyA9IDEsIGxhYmVscyA9IGMoIkIiLCAiQyIsICJEIikpCldCRmlnNQpgYGAKCiMjIEZvdXIgcGFuZWwgZmlndXJlIG9mIFdlYmVyIGFuZCBCaWFuY2hpIGVxdWl2YWxlbnQgZGF0YQpgYGB7ciBmaWcuaGVpZ2h0ID0gNiwgZmlnLndpZHRoID0gOC41fQpXQmNvbWJpbmVkIDwtIHBsb3RfZ3JpZChXQkNvbG9yTWFwICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMCwzLDAsIDMpLCAiY20iKSksIFdCRmlnNSwgbmNvbCA9IDEsIGxhYmVscyA9IGMoIkEiLCAiIikpCldCY29tYmluZWQKCmdnc2F2ZSgiZmlndXJlcy9XQk1vZGVsVmFsaWRhdGlvbi5wbmciKQpgYGAKCiMgRmlndXJlIFM4CiMjIFAxNiBGbHV4IAoKIyMjIEZsdXgKYGBge3IgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0Kc2NpZW50aWZpY18xMCA8LSBmdW5jdGlvbih4KSB7cGFyc2UodGV4dD1nc3ViKCJlXFwrKiIsICIgJSolIDEwXiIsIHNjYWxlczo6c2NpZW50aWZpY19mb3JtYXQoKSh4KSkpIH0KI2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNzYyMjg3L2hvdy1jYW4taS1mb3JtYXQtYXhpcy1sYWJlbHMtd2l0aC1leHBvbmVudHMtd2l0aC1nZ3Bsb3QyLWFuZC1zY2FsZXMKI2phY29iX21hZ25pdHVkZSA8LSBmdW5jdGlvbih4KXtleHByZXNzaW9uKDEwXnJvdW5kKGxvZzEwKHgpKSl9CgpjYjEwIDwtIGMoJyNhNmNlZTMnLCcjMWY3OGI0JywnI2IyZGY4YScsJyMzM2EwMmMnLCcjZmI5YTk5JywnI2UzMWExYycsJyNmZGJmNmYnLCcjZmY3ZjAwJywnI2NhYjJkNicsJyM2YTNkOWEnKQpwbHRGbHhQMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lICNmaWx0ZXIoREZQID4gMSkgJT4lICNmaWx0ZXIocHJvZmlsZSAlaW4lIGMoInN0bl8wNDMiLCAicDE2bl8xMDAiKSkgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBGbHV4X1Ntb290aCwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSAgKyBnZW9tX3BvaW50KHNpemUgPSAzLCBzdHJva2UgPSAxKSsKICBnZW9tX3BhdGgoKSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTAwMCwgMCkpKwogIHNjYWxlX3hfbG9nMTAobGltaXRzID0gYygzNSwgMTUwKSxicmVha3MgPSBzZXEoZnJvbSA9IDIwLCB0byA9IDE1MCwgYnkgPSAyMCkpICsKICAgc2NhbGVfY29sb3JfZ3JhZGllbnQyKGxvdyA9ICJkYXJrZ3JlZW4iLCBtaWQgPSAiZ3JheTgwIiwgaGlnaCA9ICJwdXJwbGUiLCBtaWRwb2ludCA9IDEwKSArIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lID0gIkRheSBvZiBNb250aCIsIHZhbHVlcyA9IHJlcCgyMToyNSwgMikpICsgCiAgc2NhbGVfZmlsbF9ncmFkaWVudG4obmFtZSA9ICJIb3VyIG9mIERheSIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICAKbGFicyh4ID0gYnF1b3RlKFNtb290aGVkfkZsdXh+KMK1bW9sfkMvbV4yL2QpKSwgeSA9ICJEZXB0aCAobSkiKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAuMyksIGxlZ2VuZC5zcGFjaW5nID0gdW5pdCguMSwgImNtIikpCiMgCiMgCiMgCiMgcGx0Rmx4Tm9MZWdlbmQgPC0gcGx0Rmx4ICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIHBsdEZseExlZ2VuZCA8LSBnZXRfbGVnZW5kKHBsdEZseCkKIyAKcGx0Rmx4UDE2CiMgI3Bsb3RseTo6Z2dwbG90bHkocGx0MSkKYGBgCgojIyMgUmF0ZSBvZiBjaGFuZ2Ugb2YgZmx1eCAtLSBmaWZ0aCByb290IHRyYW5zZm9ybWVkCmBgYHtyIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNiMTAgPC0gYygnI2E2Y2VlMycsJyMxZjc4YjQnLCcjYjJkZjhhJywnIzMzYTAyYycsJyNmYjlhOTknLCcjZTMxYTFjJywnI2ZkYmY2ZicsJyNmZjdmMDAnLCcjY2FiMmQ2JywnIzZhM2Q5YScpCnBsdERlbHRhM1AxNiA8LSBiZHMgJT4lIGZpbHRlcihwcm9qZWN0ID09ICJQMTYiKSAlPiUgI2ZpbHRlcihERlAgPiAxKSAlPiUgI2ZpbHRlcihwcm9maWxlICVpbiUgYygic3RuXzA0MyIsICJwMTZuXzEwMCIpKSAlPiUKICBnZ3Bsb3QoYWVzKHkgPSBkZXB0aCwgeCA9IHByYWNtYTo6bnRocm9vdChERi9EWiwgNSksIGdyb3VwID0gZmFjdG9yKHRpbWUpKSkgICsgZ2VvbV9wb2ludChzaXplID0gMywgc3Ryb2tlID0gMSkrCiAgZ2VvbV9wYXRoKCkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEwMDAsIDApKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygtMSwgLjEpLCBicmVha3MgPSBzZXEoZnJvbSA9IC0yLCB0byA9IC43NSwgYnkgPSAwLjUpKSArCiAgI3NjYWxlX3hfbG9nMTAoKSArCiAgIHNjYWxlX2NvbG9yX2dyYWRpZW50Mihsb3cgPSAiZGFya2dyZWVuIiwgbWlkID0gImdyYXk4MCIsIGhpZ2ggPSAicHVycGxlIiwgbWlkcG9pbnQgPSAxMCkgKyBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciIsIGJyZWFrcyA9IGMoMCwgNiwgMTIsIDE4LCAyNCksIGNvbG9ycyA9IGMoImJsYWNrIiwgImJsdWUiLCAid2hpdGUiLCAib3JhbmdlIiwgImJsYWNrIikpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMjAwLCBjb2xvciA9ICJkYXJrZ3JlZW4iKSsKICBsYWJzKHggPSBicXVvdGUoKERGL0RaKV57MS81fX4owrVtb2xDL21eMy9kKV57MS81fSksIHkgPSAiRGVwdGggKG0pIikgKyB0aGVtZShsZWdlbmQucG9zID0gIm5vbmUiKQogICNsYWJzKHggPSAiKERGL0RaKSBeIDEvNSAowrVtb2wgQy9tXjMvZCkgXiAxLzUiKQoKcGx0RGVsdGEzUDE2CiNwbG90bHk6OmdncGxvdGx5KHBsdDFwb3MpCmBgYAoKIyMjIERpZmZlcmVuY2UgZnJvbSBtb2RlbApgYGB7ciBmaWcud2lkdGggPSA2LCBmaWcuaGVpZ2h0ID0gNH0Kb3Ntc19wMTYgPC0gYmRzICU+JSBmaWx0ZXIocHJvamVjdCA9PSAiUDE2IikgJT4lCiAgZ2dwbG90KGFlcyh5ID0gZGVwdGgsIHggPSBwcmFjbWE6Om50aHJvb3Qob3Nwc0RaLCAzKSwgZ3JvdXAgPSBmYWN0b3IodGltZSkpKSArIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgZ2VvbV9wYXRoKCkgKyBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMDAwLCAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKC0xLCAxKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDApICsgICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZSA9ICJEYXkgb2YgTW9udGgiLCB2YWx1ZXMgPSByZXAoMjE6MjUsIDIpKSArIGxhYnMoeCA9ICJPYnNlcnZlZCAtIE1vZGVsZWQgU21hbGwgUGFydGljbGUgRmx1eCBcbiDCtW1vbC9tXjMvZGF5IikgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKG5hbWUgPSAiSG91ciBvZiBEYXkiLCBicmVha3MgPSBjKDAsIDYsIDEyLCAxOCwgMjQpLCBjb2xvcnMgPSBjKCJibGFjayIsICJibHVlIiwgIndoaXRlIiwgIm9yYW5nZSIsICJibGFjayIpKSArIGdlb21faGxpbmUoeWludGVyY2VwdCA9IFBob3RpY0Jhc2UsIGNvbG9yID0gImRhcmtncmVlbiIpIApwbG90bHk6OmdncGxvdGx5KG9zbXNfcDE2KQojZ2dzYXZlKCIuLmZpZ3VyZXMvRmx1eFNpemVTaGlmdC5zdmciCgpgYGAKCiMjIyBDb21iaW5lIGV2ZXJ5dGhpbmcgdG9nZXRoZXIKYGBge3IgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodD04fQpwbG90X2dyaWQoCiAgcGx0Rmx4UDE2LAogIHBsdERlbHRhM1AxNiwKICBvc21zX3AxNgopCgpnZ3NhdmUoImZpZ3VyZXMvUDE2Rmx1eFJlbGF0ZS5zdmciKQpnZ3NhdmUoImZpZ3VyZXMvUDE2Rmx1eFJlbGF0ZS5wbmciKQpgYGAKCiMgRmlndXJlIFMxMAojIyBGbHV4IGF0dGVudWF0aW9uIGV4YW1wbGUKClRha2Ugb25lIHByb2ZpbGUsIGF0dGVudWF0ZSBpdCwgYW5kIHNob3cgd2hhdCBpdCBsb29rcyBsaWtlCmBgYHtyfQpzb3VyY2UoIk1vZGVsU3R1ZmYuUiIpCmBgYAoKCmBgYHtyfQpzY2FuX2Zvcl9leGFtcGxlIDwtIGJkcyAlPiUgZmlsdGVyKHByb2plY3QgPT0gIkVUTlAiLCBkZXB0aCA8IDUwMCwgZGVwdGggPiAyMDApICU+JSBzZWxlY3QocHJvZmlsZSwgZGVwdGgsIERGUCwgdXNlX3RoaXNfREZQLCBvc3BzRFopCgojbG9jX3N0YXRpb24gPSAic3RuXzAzNiIKbG9jX3N0YXRpb24gPSAic3RuXzA0MyIKbG9jX2RlcHRoID0gMjI1CmxvY19wcmV2X2RlcHRoID0gMTEyLjUKCmFsbERGUHMgPC0gYmRzICU+JSBmaWx0ZXIocHJvZmlsZSA9PSBsb2Nfc3RhdGlvbiwgZGVwdGggPj0gbG9jX3ByZXZfZGVwdGgsIGRlcHRoIDw9IGxvY19kZXB0aCkgJT4lIHN1bW1hcml6ZShERlAgPSBwcm9kKERGUCksIHVzZV90aGlzX0RGUCA9IHByb2QodXNlX3RoaXNfREZQKSkKCmxvY19ERlAgPC0gIGFsbERGUHMgJT4lIHB1bGwoREZQKQpsb2NfdXNlX0RGUCA8LSBhbGxERlBzICU+JSBwdWxsKHVzZV90aGlzX0RGUCkKCgpmb3Jfc2luZ2xlX2Rpc2FnIDwtIGJlcyAlPiUgZmlsdGVyKHByb2ZpbGUgPT0gbG9jX3N0YXRpb24sIGRlcHRoICVpbiUgYyhsb2NfcHJldl9kZXB0aCwgbG9jX2RlcHRoKSkgJT4lIHNlbGVjdChkZXB0aCwgbGIsIG5ucF9zbW9vdGgpICU+JQogIG11dGF0ZShkZXB0aCA9IHJlY29kZShkZXB0aCwgYDExMi41YCA9ICJTaGFsbG93IiwgYDIyNWAgPSAiRGVlcCIpKSAlPiUgIyBJIGhhdmUgbm8gaWRlYSBob3cgdG8gbm90IGhhcmQgY29kZSB0aGlzIGJpdAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBkZXB0aCwgdmFsdWVzX2Zyb20gPSBubnBfc21vb3RoKSAKCndpdGhfZGlzYWcgPC0gZm9yX3NpbmdsZV9kaXNhZyAlPiUKICBtdXRhdGUoUHJlZGljdGVkX0RlZXAgPSByZW1pbl9zbW9vdGhfc2h1ZmZsZShTaGFsbG93LCBsb2NfdXNlX0RGUCkpIAojcmVtaW5fc21vb3RoX3NodWZmbGUoZm9yX3NpbmdsZV9kaXNhZyRTaGFsbG93LGxvY191c2VfREZQKQoKZm9yX3Bsb3RfZGlzYWcgPC0gd2l0aF9kaXNhZyAlPiUgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtbGIpICU+JSAjZmlsdGVyKGxiIDw9IDUpICU+JQogIG11dGF0ZShuYW1lID0gZmFjdG9yKG5hbWUsIGxldmVscyA9IGMoIlNoYWxsb3ciLCAiRGVlcCIsICJQcmVkaWN0ZWRfRGVlcCIpKSkgJT4lCiAgbXV0YXRlKG5hbWUgPSByZWNvZGVfZmFjdG9yKG5hbWUsIFNoYWxsb3cgPSAiU2hhbGxvdyAoMTEyLjVtKSIsIERlZXAgPSAiRGVlcCAoMjI1bSkiLCBQcmVkaWN0ZWRfRGVlcCA9ICJQcmVkaWN0ZWQgRGVlcCAoMjI1bSkiKSkKCmZvcl9wbG90X2Rpc2FnICU+JSBnZ3Bsb3QoYWVzKHggPSBsYiwgeSA9IHZhbHVlLCBzaGFwZSA9IG5hbWUpKSArIGdlb21fcG9pbnQoKSArIHNjYWxlX3hfbG9nMTAoKSArIHNjYWxlX3lfbG9nMTAoKSArIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDEsIDYsIDMpKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKyBsYWJzKHggPSAiUGFydGljbGUgU2l6ZSAobW0pIiwgeSA9ICJOb3JtYWxpemVkIFBhcnRpY2xlIEFidW5kYW5jZSAoIy9ML21tKSIpCgpnZ3NhdmUoImZpZ3VyZXMvRGlzYWdFeGFtcGxlLnBuZyIpCmdnc2F2ZSgiZmlndXJlcy9EaXNhZ0V4YW1wbGUuc3ZnIikKYGBgCgoKCg==